OwlCoder
Django - получение доступа к request из любого места
Иногда в django при разработке проекта требуется получить доступ к текущему объекту request, но это не удаётся сделать ввиду каких-то архитектурных особенностей. Бывает что просто неудобно прокидывать этот request везде, где только можно. Было бы гораздо удобнее где-то получить его через некий модуль - синглтон. Но джанга - в отличии от PHP представляет собой постоянно работающий процесс, и каждый request у него привязан к соответствующему потоку. То есть нам нужен реквест не абы какой, а именно текущего потока. Так вот, чтобы осуществить такой функционал можно создать несложный middleware + метод получения запроса, привязанного к потоку.
Далее прилагаю код этого middleware, который, например, можно добавть в файл приложения main/global_request_middleware.py.
Подключаем его в settings и вызываем метод get_request() там, где нам нужен запрос. Вот собственно и всё.
import threading
from django.http.request import HttpRequest
from typing import Union
GLOBAL_REQUEST_STORAGE = threading.local()
class GlobalRequestMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
GLOBAL_REQUEST_STORAGE.request = request
try:
return self.get_response(request)
finally:
del GLOBAL_REQUEST_STORAGE.request
def get_request() -> Union[HttpRequest, None]:
try:
return GLOBAL_REQUEST_STORAGE.request
except AttributeError:
return None