Подтвердить что ты не робот

Django: объект WSGIRequest не имеет атрибута "пользователь" на некоторых страницах?

Я хочу установить cookie, если пользователь зарегистрирован или нет.

My Middleware:

class UserStatus(object):
    def process_response(self,request,response):
        user_status = 1 if request.user.is_authenticated() else 0
        max_age = (20)*52*7*24*60*60 # 20 years (After expiry, cookie gets deleted)
        response.set_cookie(user_status_cookie,user_status,max_age)
        return response

Добавлен в MIDDLEWARE_CLASSES в settings.py в конце.

Проблема:

  • Ошибка: объект WSGIRequest не имеет атрибута 'user'
  • Почему, когда у меня уже есть аутентификация и сеанс посредников?
  • Кроме того, некоторые страницы работают плавно, когда некоторые из них дают эту ошибку.
  • Что я делаю неправильно?

Пожалуйста, помогите.

4b9b3361

Ответ 1

В соответствии с FineManual:

В фазах ответа (process_response() и промежуточного программного обеспечения process_exception()) классы применяются в обратном порядке, снизу вверх

Итак, я бы сказал, что вам лучше добавить свое промежуточное программное обеспечение перед средним сервером auth и session (при условии, что он обрабатывает только ответ).

Говоря это, я немного озадачен тем, что у вас есть только ошибка на некоторых страницах.

Ответ 2

В последнее время возникла проблема с той же проблемой, и выяснилось, что это произошло, когда URL-адрес обращается без конечной косой черты, а для параметра APPEND_SLASH установлено значение true:


Django обрабатывает начальный запрос

  • CommonMiddleware.process_request
    • Перенаправляет в newurl, который имеет завершающую черту
  • process_response все еще выполняется в пользовательском промежуточном программном обеспечении
    • request.user нет
  • HTTP 301

Затем Django обрабатывает запрос url с завершающим косой чертой

  • process_response запускается в пользовательском промежуточном программном обеспечении
    • request.user теперь присутствует

Кто-нибудь знает, почему некоторые основные атрибуты (пользователь и сеанс) недоступны в process_response после постоянного перенаправления?

Ответ 3

Таким образом, это связано с тем, что APPEND_SLASH применяется с помощью перенаправления Django Common Middleware, предотвращая запуск process_request() в AuthenticationMiddleware (который добавляет атрибут user), но ваш process_response все еще выполняется.

Здесь как Django Process Middleware ACTUALLY Works (от django/core/handlers/base.py в Django 1.6)

  • Вы запрашиваете URL-адрес, который не имеет завершающей косой черты. Итак, yourdomain.com/view. Это запустит поток промежуточного программного обеспечения.
  • Как только запрос достигнет CommonMiddleware, промежуточное ПО видит, что нет косой черты и возвращает http.HttpResponsePermanentRedirect(newurl). Это немедленно останавливает выполнение любого дополнительного process_requests, в том числе один в AuthenticationMiddleware, который добавляет атрибут user к request
  • Поскольку CommonMiddleware не возвратил исключение (включая Http404), django теперь получит ответ от промежуточного программного обеспечения и запустит его через КАЖДОЕ process_response() в КАЖДОЕ промежуточное программное обеспечение, указанное в MIDDLEWARE_CLASSES, независимо от того, что у промежуточного программного обеспечения process_request() появилась возможность запускать.

Единственный реальный способ исправить это - либо переместить ваш код в метод process_request(), расположенный после AuthenticationMiddleware в MIDDLEWARE_CLASSES, либо определить через hasattr(), если объект request имеет атрибут user.

Ответ 4

У вас есть это промежуточное ПО?:

'django.contrib.auth.middleware.AuthenticationMiddleware'

И это промежуточное ПО запускается перед вашим промежуточным программным обеспечением?

Ответ 5

У меня была аналогичная проблема, некоторые из моих страниц не имеют пользователя в запросе, поэтому в моем промежуточном программном обеспечении я быстро проверяю

if not hasattr(request, 'user'):
    return response

Ответ 6

В рамках некоторого промежуточного программного обеспечения или любого другого кода, который выполняется перед django AuthenticationMiddleware (который отвечает за назначение объекта .user для запроса объекта), может возникнуть исключение.

Тогда при доступе к переменной .user будет атрибут AttributeError.

Например, любое исключение, вызванное до того, как AuthenticationMiddleware могло бы запустить, может вызвать просмотр ошибки. Вы получите ошибку, указанную в заголовке вопроса, если представление ошибки зависит от request.user.