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'
- Почему, когда у меня уже есть аутентификация и сеанс посредников?
- Кроме того, некоторые страницы работают плавно, когда некоторые из них дают эту ошибку.
- Что я делаю неправильно?
Пожалуйста, помогите.
Ответы
Ответ 1
В соответствии с FineManual:
В фазах ответа (process_response() и промежуточного программного обеспечения process_exception()) классы применяются в обратном порядке, снизу вверх
Итак, я бы сказал, что вам лучше добавить свое промежуточное программное обеспечение перед средним сервером auth и session (при условии, что он обрабатывает только ответ).
Говоря это, я немного озадачен тем, что у вас есть только ошибка на некоторых страницах.
Ответ 2
В последнее время возникла проблема с той же проблемой, и выяснилось, что это произошло, когда URL-адрес обращается без конечной косой черты, а для параметра APPEND_SLASH установлено значение true:
Django обрабатывает начальный запрос
- CommonMiddleware.process_request
- Перенаправляет в newurl, который имеет завершающую черту
- process_response все еще выполняется в пользовательском промежуточном программном обеспечении
- 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.