19

如果用户登录与否,我想设置一个 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_CLASSESsettings.py 中。

问题:

  • 错误:“WSGIRequest”对象没有属性“用户”
  • 为什么,当我已经激活了身份验证和会话中间件时?
  • 此外,有些页面运行流畅,有些页面出现此错误。
  • 我究竟做错了什么 ?
4

6 回答 6

25

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


Django 处理初始请求

  • CommonMiddleware.process_request
    • 重定向到带有斜杠的 newurl
  • process_response 仍在自定义中间件中运行
    • request.user 不存在
  • HTTP 301

然后 Django 处理带有斜杠的 url 请求

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

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

于 2013-02-10T02:11:53.103 回答
17

所以它与APPEND_SLASHDjango Common Middleware 通过重定向应用有关,防止运行process_request()in AuthenticationMiddleware(添加user属性)但您process_response仍在运行。

以下是 Django 进程中间件的实际工作方式(来自django/core/handlers/base.pyDjango 1.6)

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

解决此问题的唯一真正方法是将代码移动到process_request()位于 in 之后的方法AuthenticationMiddleware中,或者MIDDLEWARE_CLASSES检测对象是否具有属性。hasattr()requestuser

于 2014-01-13T20:42:13.073 回答
12

根据 FineManual:

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

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

话虽如此,我对您仅在某些页面上出现错误这一事实感到有些困惑???

于 2012-06-27T10:17:35.693 回答
9

你有激活这个中间件吗?:

'django.contrib.auth.middleware.AuthenticationMiddleware'

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

于 2012-06-27T10:18:53.657 回答
4

我有一个类似的问题,我的一些页面在请求中没有用户,所以在我的中间件中我做了一个快速检查

if not hasattr(request, 'user'):
    return response
于 2014-02-10T15:46:10.717 回答
0

There could be an exception raised within some middleware or any other code that runs before the django's AuthenticationMiddleware (which is responsible for assigning the .user to request object).

Then there will be an AttributeError upon accessing the .user variable.

For example, any exception triggered before the AuthenticationMiddleware had a chance to run might cause the error view to execute. You'll get the error as mentioned in the title of the question, if the error view depends on request.user.

于 2015-11-22T16:27:50.247 回答