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

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

Мое Промежуточное ПО:

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 in settings.py в конце.

проблема:

  • ошибка: объект "WSGIRequest" не имеет атрибута "user"
  • почему, когда у меня уже активна аутентификация и промежуточные программы сеанса ?
  • кроме того, некоторые страницы работают гладко, где некоторые дают это ошибка.
  • что я делаю не так ?

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

6 ответов


согласно FineManual:

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

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

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


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


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

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

Django затем обрабатывает запрос url с конечной косой чертой

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

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


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

вот как на самом деле работает промежуточное ПО процесса Django (от django/core/handlers/base.py в Django 1.6)

  1. вы запрашиваете URL-адрес, который не имеет конечной косой черты. Так что yourdomain.com/view. Это запускает поток промежуточного ПО.
  2. запрос достигает CommonMiddleware, промежуточное ПО видит, что нет косой черты и возвращает http.HttpResponsePermanentRedirect(newurl). Это немедленно останавливает любые дополнительные process_requests от запуска, в том числе один в AuthenticationMiddleware что добавить до request
  3. , потому что CommonMiddleware не вернули исключение (включая Http404), django сейчас примет ответ от middleware и запустить его через каждые process_response() в каждом промежуточном по, перечисленных в MIDDLEWARE_CLASSES, независимо от того, если это промежуточное ПО process_request() имел возможность бежать.

единственный реальный способ исправить это - либо переместить код в process_request() способ находится после AuthenticationMiddleware на MIDDLEWARE_CLASSES или обнаружить с помощью hasattr() если .


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

'django.contrib.auth.middleware.AuthenticationMiddleware'

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


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

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

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

тогда будет AttributeError при доступе к.пользовательская переменная.

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