Django:WSGIRequest'对象在某些页面上没有属性'user'?

Yug*_*dle 18 python django wsgi django-middleware

我想在用户登录时设置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
Run Code Online (Sandbox Code Playgroud)

最后添加到MIDDLEWARE_CLASSESsettings.py中.

问题:

  • 错误:'WSGIRequest'对象没有属性'user'
  • 为什么,当我已经启用身份验证和会话中间件时?
  • 此外,有些页面正在顺利运行,因为有些页面会出现此错误.
  • 我究竟做错了什么 ?

Yac*_*zmi 25

最近遇到了同样的问题,发现它是在没有尾部斜杠的情况下访问URL时发生的,并且APPEND_SLASH设置设置为true:


Django处理初始请求

  • CommonMiddleware.process_request
    • 重定向到newurl,其中包含尾部斜杠
  • process_response仍在自定义中间件中运行
    • request.user不存在
  • HTTP 301

然后Django使用尾部斜杠处理url的请求

  • process_response在自定义中间件中运行
    • request.user现在存在

任何人都知道为什么在永久重定向后,process_response中无法访问某些主要属性(用户和会话)?


Nic*_*tal 16

因此它APPEND_SLASH与通过Django Common Middleware的重定向应用有关,防止process_request()in AuthenticationMiddleware(添加user属性)被运行但process_response仍在运行.

以下是Django Process Middleware ACTUALLY如何工作(来自django/core/handlers/base.pyDjango 1.6)

  1. 您请求的URL不具有尾部斜杠.所以yourdomain.com/view.这启动了中间件流程.
  2. 一旦请求到达CommonMiddleware,中间件就会看到没有斜杠并返回一个http.HttpResponsePermanentRedirect(newurl).这会立即停止process_requests运行任何其他内容,包括AuthenticationMiddleware添加user属性的其中一个request
  3. 因为CommonMiddleware没有返回异常(包括Http404),django现在将从中间件获取响应并process_response()在每个列出的中间件中运行它MIDDLEWARE_CLASSES,无论该中间件process_request()是否有机会运行.

解决这个问题的唯一真正方法是将代码移动到process_request()位于AuthenticationMiddlewarein 之后的方法中,MIDDLEWARE_CLASSES或者检测via hasattr()是否request具有user属性.

  • 这很棒!一旦我按照这个顺序放置中间件我的应用程序工作:('django.contrib.auth.middleware.AuthenticationMiddleware','MyMiddleware','django.middleware.common.CommonMiddleware') (3认同)

bru*_*ers 12

根据FineManual:

在响应阶段(process_response()和process_exception()中间件),类以相反的顺序应用,从下往上

所以我说你最好在auth和会话中间件之前添加你的中间件(假设它只处理响应).

这就是说,我有点困惑的事实是你只有一些页面上的错误???

  • 我猜有些页面没有附加尾部斜杠. (5认同)

Goi*_*oin 9

你有活跃的这个中间件吗?:

'django.contrib.auth.middleware.AuthenticationMiddleware'
Run Code Online (Sandbox Code Playgroud)

而这个中间件在你的中间件之前运行?