Как хранить данные глобально для одного запроса в Django?

Я хочу подготовить свой веб-сервис Django для распределенных запросов с использованием облачных вычислений (без сохранения состояния!). Поэтому мне нужно сделать свои запросы полностью модульными и позаботиться о том, чтобы данные из предыдущего запроса не использовались. Поскольку для некоторых запросов мне нужно много данных и функций, нецелесообразно передавать эти данные каждой функции.

Вопрос : Какие есть возможности для хранения данных «глобально» для одного запроса?

Насколько я вижу, есть две возможности, но обе они не соответствуют моим потребностям:

1. Джанго сессия

Сохраните данные в request.session (используя промежуточное программное обеспечение «django.contrib.sessions.middleware.SessionMiddleware»).

Когда я правильно понял, данные все еще сохраняются после запроса на следующие запросы того же пользователя, пока пользователь не выйдет из системы.

Это верно?

В моих тестах данные пусты для каждого нового запроса. Но я не понимаю почему. И все же у меня нет ручки для запроса во всех моих функциях.

Для получения дополнительной информации о сессиях Django см .:

2. Python Global Keyword

Храните данные в глобальных переменных Python.

Эти данные хранятся независимо от запросов и сессий Django.

Для получения дополнительной информации о глобальных переменных см .:

Workaraound

В качестве неприятного обходного пути для обоих решений я могу удалить «глобальные» данные в конце каждого запроса, чтобы каждый запрос оставался независимым от других.

Есть ли лучший способ пойти?

Как эта ситуация подразумевается в Джанго?

Заранее спасибо за вашу поддержку.

Всего 1 ответ


Это может быть не очень эффективным решением, но вы можете сохранить его в пространстве потока.

Я использовал это, чтобы добавить уникальный идентификатор - request_id к каждому запросу и добавить его в формат регистратора. Таким образом, мне не нужно было передавать request_id каждой функции.

init.py для моего промежуточного программного обеспечения:

import threading
local = threading.local()

Это было мое специальное промежуточное ПО:

import json
import uuid
import traceback
from django.utils.deprecation import MiddlewareMixin
class RequestIDMiddleware(MiddlewareMixin):
    def process_request(self, request):
        de_run_id = str(uuid.uuid4())
        local.de_run_id = de_run_id
        request.de_run_id = de_run_id
        if request.body:
            try:
                req = json.loads(request.body)
                if req.get("app_id"):
                    local.app_id = req["app_id"]
                elif req.get("APP_DATA", {}).get("metadata", {}).get("app_id"):
                    local.app_id = req["APP_DATA"]["metadata"]["app_id"]
                else:
                    local.app_id = None
            except Exception, e:
                local.app_id = None
        else:
            local.app_id = None

И это был мой собственный фильтр логов:

import logging
from xxxx.middleware import local


class RequestIDFilter(logging.Filter):
    def filter(self, record):
        record.de_run_id = getattr(local, 'de_run_id')
        record.app_id = getattr(local, "app_id")
        return True

Вы можете определить локальный в init.py вашего проекта. а затем перезаписать его промежуточным программным обеспечением (или любым другим способом) и получить доступ к local протяжении всего проекта.

Является ли это лучшим решением для вас, зависит от множества факторов, обсуждаемых здесь


Есть идеи?

10000