【问题标题】:Why django makes many session object in database?为什么 django 在数据库中创建许多会话对象?
【发布时间】:2013-04-02 19:18:40
【问题描述】:

我有一个带有名为 'app' 的应用程序的香草 django 项目。它有views.py 和middleweres.py。

#views.py
from django.http.response import HttpResponse

def home(request):
    return HttpResponse('')

#settings.py

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'app.middlewares.M',
)

#middlewares.py
class M(object):
    def process_request(self, request):
        request.session['a']='a'

Django 在每次请求时都会在 db 中的会话表中添加一行。为什么?

UPD:我还是很困惑。我为这个问题做了一个 github 项目:https://github.com/vinograd19/django-session-problem/ 你可以在那里找到我的代码并在你的机器上运行它

【问题讨论】:

  • 你能转储会话数据吗?您是否知道您正在修改每个 process_request 中的会话?
  • 有 'original' session {'_auth_user_id': 1L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend','a':'a'} 和其他像 {' a':'a'}
  • 在没有 app.middlewares.M 的情况下也会发生这种情况吗?

标签: django django-sessions


【解决方案1】:

您的自定义中间件 M 正在修改每个请求的会话字典 (Writing your own middleware):

在 Django 决定执行哪个视图之前,每个请求都会调用 process_request()。

即使您正在修改每个请求的会话,每个用户(同一浏览器上的同一访问者)也应该只有一行。如果同一个访问者发出多个请求,他对应的会话行应该在每个请求上更新(因为你的中间件'M')。不会为同一访问者创建额外的行,但会在新访问者访问您的网站时创建新行。来自 Django 文档:

考虑数据库后端会发生什么。当用户登录时,Django 会在 django_session 数据库表中添加一行。每次会话数据更改时,Django 都会更新此行。如果用户手动注销,Django 会删除该行。但是,如果用户没有注销,则该行永远不会被删除。文件后端也会发生类似的过程。

如果您在 DB sessions 表中发现了很多行,那么您可能有需要清除的过期会话 (Clearing the session store)

Django 不提供过期会话的自动清除。因此,定期清除过期会话是您的工作。为此,Django 提供了一个清理管理命令:clearsessions。建议定期调用此命令,例如作为每日 cron 作业。

在这种情况下,您应该拨打clearsessions command

django-admin.py clearsessions

您应该设置一个 cron 作业来定期调用此命令并清除过期的会话。

【讨论】:

  • 对不起,我没听懂。你的意思是django在实现M中间件时不知道用户对象?如果是这样,messages 中间件如何在不知道用户对象的情况下工作?
  • Django 确实知道用户对象,如果用户已登录(请参阅how to get user from session)。如果用户未登录,那么您将有一个匿名会话。检查会话表中所有重复行的过期日期。您可能会发现所有“重复”都是过期会话。
  • 正如我所说,会话表会根据请求更新。会话没有过期。
【解决方案2】:

来自docs

保存会话时

默认情况下,Django 只保存到会话中 会话被修改时的数据库——也就是说,如果它的任何一个 字典值已被分配或删除:

【讨论】:

  • 所以?会话字典没有被改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 2014-01-02
相关资源
最近更新 更多