来自Django's documentation for set_expiry
:
读取会话不会被视为过期目的的活动。会话到期时间是从会话修改的最后一次计算出来的。
Django SESSION_COOKIE_AGE
设置的默认值为1209600
(2周,以秒为单位)。因此,如果会话在1月1日午夜创建,它将设置为在1月15日午夜到期。但是,如果该会话在1月14日午夜被修改,那么它将在1月28日午夜而不是原来的1月15日午夜到期。
我对两周的默认生命周期感到满意,但我想知道最有效的方法,因此所有会话在创建后的两周内都会过期 - 即使它们被修改。似乎我必须编写一些中间件来检查会话创建时间,然后将到期时间设置为两周后,但似乎必须有一种比这更有效的方法。
答案 0 :(得分:2)
您应该扩展django.contrib.session.backends.db.SessionBase
类并修改行为,因此只需快速查看该类,您就可以查看save(...)
和get_expiry_date(...)
方法。
以下是自定义会话存储类的示例,如果已存在具有该密钥的会话,则不会更新会话的expiry_date
from django.contrib.sessions.backend.db import SessionStorage
class MySessionStore(SessionStore):
def save(self, must_create=False):
"""
Saves the current session data to the database. If 'must_create' is
True, a database error will be raised if the saving operation doesn't
create a *new* entry (as opposed to possibly updating an existing
entry).
"""
if self.session_key is None:
return self.create()
existing_session = Session.objects.filter(session_key=self.session_key)
expire_date = self.get_expiry_date()
if existing_session.exists():
# Here we select the original expire_date from the database
# so when the session is modified and saved, expire_date
# remains unchanged
if existing_session.first().expire_date is not None:
expire_date = existing_session.first().expire_date
obj = Session(
session_key=self._get_or_create_session_key(),
session_data=self.encode(self._get_session(no_load=must_create)),
expire_date=expire_date
)
using = router.db_for_write(Session, instance=obj)
try:
with transaction.atomic(using=using):
obj.save(force_insert=must_create, using=using)
except IntegrityError:
if must_create:
raise CreateError
raise
现在我们有一个自定义会话类,每次修改会话时都不会更新到期日期,我们必须使用SESSION_ENGINE
设置为SESSION_ENGINE='path.to.MySessionStore'
的自定义会话类
我还没有测试过这个解决方案,我只是在回答一个问题:)