Как получить доступ к запросу в models.py, джанго

#python #django

Вопрос:

 @property def get_maca(self, request):  if request.user.name == "example":  return self  

Я хочу сделать что-то подобное. Если имя пользователя является примером, верните этот объект.

Как получить доступ к такому запросу?

Комментарии:

1. Ты не можешь. База данных (модель) не имеет понятия о запросе.

2. Вам нужно передать его в качестве аргумента, поэтому вы не можете его использовать @property . Но мне кажется, что это плохая практика. Как упоминал @Selcuk, модели не имеют понятия о логике представлений и не должны беспокоиться о ней. Если вам что-то нужно из запроса, извлеките это в своем представлении и передайте методу модели

Ответ №1:

Стандартный способ-передать запрос или, в вашем случае, просто объект пользователя, от представления/маршрутизатора вплоть до моделей.

Это очень быстро выходит из-под контроля в более крупном проекте, поэтому мой подход заключается в использовании локального потока для сохранения некоторого контекста запроса, который мне нравится иметь доступным во всем проекте. Локальное хранилище потоков будет хранить данные, доступные внутри одного потока, без доступа к ним из других потоков — отлично, если вы собираетесь запускать приложение Django на рабочем сервере.

Начните с локального хранилища:

 from threading import local _active_user = local()  def activate_user(user):  if not user:  return   _active_user.value = user  def deactivate_user():  if hasattr(_active_user, "value"):  del _active_user.value  def get_user():  """Returns `(is_anonymous, user)` ."""  active_user = getattr(_active_user, "value", None)  if active_user and active_user is not AnonymousUser:  try:  return False, active_user  except AttributeError:  pass   return True, None  

Теперь все хорошо, вы можете использовать это вручную. Звонки activate_user позволят вам звонить get_user в любое место вашего проекта. Однако это может привести к ошибкам — если вы забудете позвонить deactivate_user , объект пользователя все равно будет доступен для следующего следующего запроса.

Остальная часть ответа состоит в том, чтобы показать, как сделать все автоматически.

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

 class ThreadCleanupMiddleware:  def __init__(self, get_response):  self.get_response = get_response  # One-time configuration and initialization.   def __call__(self, request):  # Executed for each request before  # the view (and later middleware) are called.   response = self.get_response(request)   # Executed for each request/response after  # the view is called.  deactivate_user()   return response  

Добавьте путь ThreadCleanupMiddleware в конец вашего settings.MIDDLEWARE списка.

Завершите с помощью микшера представлений, который автоматически активирует пользователя (это для представлений на основе классов; если вы используете функциональные представления, вместо этого это будет декоратор).:

 class ContextViewSetMixin:   def initial(self, request, *args, **kwargs):  super().initial(request, *args, **kwargs)  if request.user.is_authenticated:  activate_user(request.user)  class ContextModelViewSet(ContextViewSetMixin, viewsets.ModelViewSet):  pass