Как хранить данные глобально для одного запроса в Django? - PullRequest
1 голос
/ 15 января 2020

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

Вопрос : какие существуют возможности для хранения данных "в глобальном масштабе «для одного запроса?

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

1. Django Session

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

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

Это правильно?

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

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

2. Python Глобальное ключевое слово

Сохранение данных в python глобальных переменных.

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

Подробнее см. информацию о глобальных переменных:

Обходное решение

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

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

Как эта ситуация подразумевается в Django?

Заранее благодарим за поддержку.

1 Ответ

1 голос
/ 16 января 2020

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

Я использовал это для добавления уникального идентификатора - 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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...