gpt4 book ai didi

django - 如何防止 Django 写入某些 URL 的 django_session 表

转载 作者:行者123 更新时间:2023-12-01 03:56:16 25 4
gpt4 key购买 nike

如果我的问题与 this one 非常相似,我们深表歉意我试图解决这个问题的方法是 100% 基于该问题的答案,但我认为这稍微涉及更多,并且可能针对我不完全理解的 Django 的一部分。

我有一个用 Django 1.5 编写的 CMS 系统,其中有一些 API 可由两个桌面应用程序访问,它们不能像浏览器那样使用 cookie。

我注意到,每当其中一个应用程序进行 API 调用(每 3 秒一次)时,都会在 django_session 中添加一个新条目。 table 。仔细查看此表和代码,我可以看到特定 URL 的所有条目都被赋予相同的 session_data值但不同 session_key .这可能是因为 Django 确定当这些调用之一是从无 cookie 应用程序发出时,request.session._session_keyNone .

其结果是每天在 django_session 中创建数千个条目。表并简单地运行./manage clearsessions使用每日 cron 不会将它们从该表中删除,从而使整个数据库变得非常大而没有明显的好处。请注意,我什至尝试过 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 中是否有更好的方法来完成上述操作?任何建议将不胜感激。

最佳答案

Dirty hack:有条件地删除 session 对象。

一种方法是包含一个中间件,根据请求丢弃 session 对象。出于两个原因,这有点肮脏:

  • Session 对象首先被创建,然后被删除。 (低效)
  • 您依赖的事实是 Session 对象此时尚未写入数据库。这可能会在 future 的 Django 版本中发生变化(尽管可能性不大)。


  • 创建 custom middleware :
    class DiscardSessionForAPIMiddleware(object):

    def process_request(self, request):
    if request.path.startswith("/api/"): # Or any other condition
    del request.session

    确保在 django.contrib.sessions.middleware.SessionMiddleware 之后安装它在 MIDDLEWARE_CLASSES您的 settings.py 中的元组.

    还要检查 settings.SESSION_SAVE_EVERY_REQUEST 设置为 False (默认)。这使得它延迟写入数据库,直到数据被修改。

    替代品(未经测试)
  • 使用process_view而不是 process_request在自定义中间件中,以便您可以检查 View 而不是请求路径。优点:条件检查更好。缺点:其他中间件可能已经对 session 对象做了一些事情,然后这种方法就失败了。
  • 为您的 API View 创建一个自定义装饰器(或共享基类),删除其中的 session 对象。优势:这样做的责任在于 View ,您可能最喜欢它的地方( View 提供 API)。缺点:同上,但在更晚的阶段删除 session 对象。
  • 关于django - 如何防止 Django 写入某些 URL 的 django_session 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17086898/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com