【发布时间】:2013-06-09 19:53:08
【问题描述】:
抱歉,如果我的问题与this one 非常相似,并且我尝试解决该问题的方法是 100% 基于该问题的答案,但我认为这稍微涉及更多,并且可能针对我的 Django 的一部分不完全明白。
我有一个用 Django 1.5 编写的 CMS 系统,其中有一些 API 可供两个无法像浏览器那样使用 cookie 的桌面应用程序访问。
我注意到,每当其中一个应用程序进行 API 调用(每 3 秒一次)时,都会在 django_session 表中添加一个新条目。仔细查看此表和代码,我可以看到特定 URL 的所有条目都被赋予相同的 session_data 值,但 session_key 不同。这可能是因为 Django 确定当这些调用之一是从无 cookie 应用程序进行时,request.session._session_key 是 None。
这样做的结果是每天在django_session 表中创建数千个条目,并且仅使用每日 cron 运行 ./manage clearsessions 不会将它们从该表中删除,从而使整个数据库变得非常大而没有明显的好处。请注意,我什至尝试set_expiry(1) 处理这些请求,但./manage clearsessions 仍然没有摆脱它们。
为了通过 Django 解决这个问题,我必须覆盖 3 个 Django 中间件,因为我正在使用 SessionMiddleware、AuthenticationMiddleware 和 MessageMiddleware:
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.contrib.messages.middleware import MessageMiddleware
class MySessionMiddleware(SessionMiddleware):
def process_request(self, request):
if ignore_these_requests(request):
return
super(MySessionMiddleware, self).process_request(request)
def process_response(self, request, response):
if ignore_these_requests(request):
return response
return super(MySessionMiddleware, self).process_response(request, response)
class MyAuthenticationMiddleware(AuthenticationMiddleware):
def process_request(self, request):
if ignore_these_requests(request):
return
super(MyAuthenticationMiddleware, self).process_request(request)
class MyMessageMiddleware(MessageMiddleware):
def process_request(self, request):
if ignore_these_requests(request):
return
super(MyMessageMiddleware, self).process_request(request)
def ignore_these_requests(request):
if request.POST and request.path.startswith('/api/url1/'):
return True
elif request.path.startswith('/api/url2/'):
return True
return False
虽然上述方法有效,但我无法停止思考,我可能已经让这变得更加复杂,而且这不是最有效的方法,因为每个请求都会进行 4 次额外检查。
在 Django 中有没有更好的方法来完成上述操作?任何建议将不胜感激。
【问题讨论】:
-
其他解决方案包括更改会话引擎或会话生命周期。
-
你能根据 HTTP 标头区分非会话感知客户端吗? (以用户代理为例)
-
@Thomas 我试图通过运行 set_expiry(1) 来更改会话生命周期,但由于某种原因,运行 ./manage clearsessions 并不能清除这些 - 不太清楚为什么
-
@gertvdijk 可以工作,但我不需要在类似于上述方法的 3 个中间件中创建 HTTP 标头检查吗?
-
@purplemass 是的。然而,一个肮脏的黑客将定义一个自定义的新中间件列出在 SessionMiddleware,删除会话对象,例如
del request.session。结合将settings.SESSION_SAVE_EVERY_REQUEST留给False这应该可以防止会话被写入数据库(尽管首先创建)。
标签: django session django-sessions