2012-06-27 6 views
18

Я хочу установить файл cookie, если пользователь зарегистрировался или нет.Django: объект WSGIRequest не имеет атрибута «пользователь» на некоторых страницах?

Мои 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' не имеет атрибута 'пользователя'
  • Почему, когда у меня есть удостоверение подлинности и промежуточное программное Session активные уже?
  • Кроме того, некоторые страницы работают гладко, где некоторые из них дают эту ошибку.
  • Что я делаю неправильно?

Просьба помочь.

ответ

12

Согласно FineManual:

During the response phases (process_response() and process_exception() middleware), the classes are applied in reverse order, from the bottom up

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

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

+4

Я думаю, что некоторые страницы не добавляются с завершающим косой чертой. – Babu

9

у вас есть активный это промежуточное программное обеспечение ?:

'django.contrib.auth.middleware.AuthenticationMiddleware' 

И это промежуточное пробег до вашего промежуточного слоя?

22

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


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

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

Джанго затем обрабатывает запрос URL с замыкающей косой чертой

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

Любой знает, почему некоторые из основных атрибутов (пользователей и сеансов) не доступны в process_response после постоянной переадресации?

+0

Относительно почему: Это потому, что CommonMiddleware возвратил значение «HttpResponse» перед тем, как «AuthenticationMiddleware.process_request» имел возможность запускать, что вытесняет «AuthenticationMiddleware». «Если он возвращает объект HttpResponse, Django не будет беспокоиться о вызове какого-либо другого запроса, просмотра или промежуточного программного обеспечения исключения или соответствующего представления, он будет применять промежуточное ПО ответа к этому HttpResponse и вернуть результат». -https: //docs.djangoproject.com/en/1.7/topics/http/middleware/#process-request –

13

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

Вот как Джанго процесс Middleware действительно работает (с django/core/handlers/base.py в Django 1.6)

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

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

+3

Это замечательно! Мое приложение работало, как только я поместил промежуточное ПО в следующем порядке: («django.contrib.auth.middleware.AuthenticationMiddleware», «MyMiddleware», «django.middleware.common.CommonMiddleware») – Temuz

4

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

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

Там может быть исключение поднятый в пределах некоторого промежуточного или любой другой код который запускается до аутентификации djangoMiddleware (которая отвечает за назначение объекта .user для запроса объекта).

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

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