Декоратор Django 1.5.1 login_required не перехватывает неавторизованных пользователей

У меня есть очень типичная реализация декоратора view/login_required, и мне сообщили, что иногда два раза в день команда QA сталкивается с этой ошибкой:

ERROR: AttributeError at /plan/reviewplan/1702/ 'WSGIRequest' object has no 
attribute 'user' Request Method: GET Request URL: 
http://<ip>/plan/reviewplan/1702/ Django Version: 1.5.1

Traceback: File "/usr/lib/pymodules/python2.6/django/core/handlers/base.py" in get_response 187. 
response = middleware_method(request, response) 
File "/usr/local/lib/python2.6/dist-packages/debug_toolbar/panels/template.py" in process_response 118. pformat(k(self.request))) for k in get_standard_processors() 
File "/opt/ion/iondb/rundb/context_processors.py" in base_context_processor 25. 
if request.user: Exception Type: AttributeError at /plan/reviewplan/1702/ 
Exception Value: 'WSGIRequest' object has no attribute 'user' 

Я проверил, и в представлении действительно есть декоратор login_required. Также сообщалось о других представлениях, которые также украшены login_required.

Отдача от просмотров:

return render_to_response("template.html", context_instance=ctx, mimetype="text/html")

К вашему сведению: экземпляр ctx хранится в сеансе и часто обновляется между вызовами представления. Я унаследовал этот дизайн и ничего не могу с этим поделать. Функция, которая обрабатывает это:

def _create_context_from_session(request, next_step_name):
    ctxd = request.session['saved_plan']
    ctxd['helper'] = request.session['plan_step_helper']
    ctxd['step'] = None
    if next_step_name in ctxd['helper'].steps:
        ctxd['step'] = ctxd['helper'].steps[next_step_name]
    context = RequestContext(request, ctxd)
    return context

person Sam Hammamy    schedule 14.09.2013    source источник
comment
Каковы ваши значения для MIDDLEWARE_CLASSES и TEMPLATE_CONTEXT_PROCESSORS? Сталкиваетесь ли вы с подобными проблемами, если отключаете панель инструментов отладки django?   -  person Alasdair    schedule 14.09.2013


Ответы (1)


Может быть, в переменных контекста, хранящихся в сеансе, хранится старый экземпляр запроса (без пользовательского атрибута)? Возможно, измените возвращаемый контекст, чтобы включить текущий запрос, например:

def _create_context_from_session(request, next_step_name):
    ctxd = request.session['saved_plan']
    ctxd['request'] = request  # Add this line.
    ...

У вас есть "django.contrib.auth.context_processors.auth" в TEMPLATE_CONTEXT_PROCESSORS?

Также кажется, что у вас включена панель инструментов отладки. Проблема существует, когда вы отключаете панель инструментов отладки?

Также:

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

Можете ли вы изменить строку, упомянутую в этой трассировке:

File "/opt/ion/iondb/rundb/context_processors.py" in base_context_processor 25. 
if request.user: Exception Type: AttributeError at /plan/reviewplan/1702/ 

Вместо if request.user: сделайте if hasattr(request, 'user'): в файле /opt/ion/iondb/rundb/context_processors.py.

Выполняется ли контекстный процессор "/opt/ion/iondb/rundb/context_processors.py" после "django.contrib.auth.context_processors.auth"? Порядок выполнения процессоров контекста определяется настройкой TEMPLATE_CONTEXT_PROCESSORS.

person HankMoody    schedule 14.09.2013
comment
Экземпляр запроса, который передается в _create_context_form_session, является переменной запроса, которая передается в функцию представления и никогда не сохраняется в сеансе. Кроме того, почему панель инструментов отладки влияет на request.user? И да, django.contrib.auth.context_processors.auth добавлен в settings.py. - person Sam Hammamy; 14.09.2013
comment
Отредактировал мой ответ, может быть, на этот раз будет полезнее. - person HankMoody; 14.09.2013
comment
'django.contrib.auth.context_processors.auth' является первым в списке, за ним следует 'django.core.context_processors.request', а ниже находится пользовательский. - person Sam Hammamy; 14.09.2013