在Django中使用会话

6 投票
1 回答
4245 浏览
提问于 2025-04-16 04:06

我在使用Django的会话功能来存储登录用户的信息,还有一些其他的数据。我在阅读Django的会话相关网站时,遇到了一些问题。

根据Django网站的介绍:

Django默认会把会话信息存储在你的数据库里(使用的是模型 django.contrib.sessions.models.Session)。虽然这样很方便,但在某些情况下,把会话数据存储在其他地方会更快,所以Django可以配置成把会话数据存储在你的文件系统或者缓存中。

还有:

如果你想要持久化的缓存数据,可以把 SESSION_ENGINE 设置为 django.contrib.sessions.backends.cached_db。这样会使用一个写入缓存的方式——每次写入缓存的数据也会写入数据库。读取会话数据时,如果缓存里有,就直接用缓存,没有的话才去数据库里找。

有没有什么好的经验法则来选择使用哪种方式呢? cached_db 似乎总是更好的选择,因为最好的情况是数据在缓存里,最差的情况也在数据库里,反正都能找到。唯一的缺点是我需要设置memcached。

默认情况下, SESSION_EXPIRE_AT_BROWSER_CLOSE 被设置为 False,这意味着会话的cookie会在用户的浏览器里存储,直到 SESSION_COOKIE_AGE 设定的时间。如果你不想让用户每次打开浏览器都要重新登录,可以使用这个设置。

是否可以同时设置会话在浏览器关闭时过期,并且给它一个有效期呢?

如果值是一个整数,会话会在那段时间内没有活动后过期。例如,调用 request.session.set_expiry(300) 会让会话在5分钟后过期。

什么算是“没有活动”?

如果你使用的是数据库后端,请注意会话数据可能会在 django_session 数据库表中累积,而Django并不会自动清理这些数据。因此,你需要定期清理过期的会话。

这意味着,即使会话已经过期,数据库里仍然会有记录。那么,应该把什么代码放在哪里来“清理数据库”呢?我觉得可能需要一个单独的线程,定期(比如每小时)去数据库里检查并删除过期的会话。

1 个回答

7

有没有什么简单的规则可以帮助选择使用哪个?

没有。

Cached_db 似乎总是更好的选择……

这没问题。

在某些情况下,有很多 Django(和 Apache)进程在查询一个共同的数据库。mod_wsgi 让这种方式可以扩展得很好。缓存帮助不大,因为会话在 Apache(和 Django)进程之间是随机分配的。

是否可以同时让会话在浏览器关闭时过期,并且设置一个有效期?

我看不出为什么不可以。

什么算是“无活动”?

我猜你是在开玩笑。“活动”就是——嗯——活动。你知道的,就是在 Django 中发生的事情。Django 能看到的 GET 或 POST 请求。还有什么呢?

到底应该把“清理数据库”的代码放在哪里?

把它放在 crontab 或类似的地方。

我觉得你需要一个单独的线程,定期检查数据库(每小时一次?)

别考虑线程了(拜托)。这是一个单独的进程。每天一次就可以了。你觉得你会有多少个会话?

撰写回答