在 Django 中间件中设置 cookie

Pau*_*l J 6 python django session django-middleware

我想使用自定义 Django 中间件 (Django 1.9) 来检查匿名用户是否已接受网站的条款和条件 - 如果用户尚未单击“同意”,我将向他们显示一个对话框。

\n\n

我不需要将其存储在数据库中,而是更愿意简单地使用 Cookie。我有以下内容settings.py

\n\n
MIDDLEWARE_CLASSES = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    ...\n    'myapp.middleware.app_custom_middleware.TermsMiddleware',]\n\nSESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我在TermsMiddleware中尝试一些非常基本的东西 - 在这里我故意尝试修改请求响应只是为了让它工作:

\n\n
class TermsMiddleware(object):\n\n    def process_request(self, request):\n        request.session['myCookieKey'] = 'myCookieValue'\n        request.session.save()\n        return\n\n    def process_response(self, request, response):\n        request.session['myCookieKey'] = 'myCookieValue'\n        request.session.save()\n        return response\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我检查浏览器中的响应,我会发现它myCookieKey没有被设置,所以我认为我误解了应该如何编写。

\n\n

我可以像这样在中间件中操作会话,让它在 Django 无论如何要发送的响应中发送的 cookie 中生效吗?该文档听起来我应该能够:

\n\n
\n

它应该返回 None 或 HttpResponse 对象。如果它返回 None,Django 将继续处理该请求,执行任何其他 process_request() 中间件,然后执行 process_view() 中间件,最后执行相应的视图。如果它返回一个 HttpResponse\n 对象,Django 不会\xe2\x80\x99 调用任何其他请求、视图或\n 异常中间件或适当的视图;it\xe2\x80\x99 会将响应中间件应用于该 HttpResponse,并返回结果。

\n
\n\n

SessionStore()我还看到了文档中在视图函数之外使用的注释。理论上,我认为我不需要在这里这样做,因为我可以访问request(和response)。无论如何我都尝试过,但仍然无法让它发挥作用。

\n\n

非常感谢帮助!

\n

Dan*_*man 4

您误解的是会话和cookie之间的关系。

您不能通过修改会话来设置任意cookie。会话是数据的集合,通常存储在数据库或文件中,唯一的cookie是包含当前用户会话密钥的cookie。

您当然可以在中间件中修改会话,但无论您在哪里这样做,您都不应该期望看到 cookie 被设置。

(另外,您永远不应该像__setitem__直接调用双下划线方法一样。会话是通过类似字典的接口访问的:request.session['foo'] = 'bar'。)