终止Django会话而不考虑修改的时间
发件人: 出于过期目的,读取会话不被视为活动。会话过期时间是从上次修改会话时开始计算的 Django会话COOKIE年龄设置的默认值为终止Django会话而不考虑修改的时间,django,session,Django,Session,发件人: 出于过期目的,读取会话不被视为活动。会话过期时间是从上次修改会话时开始计算的 Django会话COOKIE年龄设置的默认值为1209600(2周,以秒为单位)。因此,如果会话在1月1日午夜创建,它将在1月15日午夜到期。但如果该会话在1月14日午夜被修改,那么它将在1月28日午夜到期,而不是原来的1月15日午夜到期 我对两周的默认生存期很满意,但我想知道最有效的方法,这样所有会话都会在创建后两周内过期,即使它们被修改。似乎我必须编写一些中间件来检查会话创建时间,然后将过期时间设置为两周
1209600
(2周,以秒为单位)。因此,如果会话在1月1日午夜创建,它将在1月15日午夜到期。但如果该会话在1月14日午夜被修改,那么它将在1月28日午夜到期,而不是原来的1月15日午夜到期
我对两周的默认生存期很满意,但我想知道最有效的方法,这样所有会话都会在创建后两周内过期,即使它们被修改。似乎我必须编写一些中间件来检查会话创建时间,然后将过期时间设置为两周后,但似乎必须有比这更有效的方法。您应该扩展
django.contrib.session.backends.db.SessionBase
类并修改其行为,因此,只要快速查看该类,您就可以查看save(…)
以及get\u expiration\u 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\u ENGINE='path.to.MySessionStore'
我还没有测试过这个解决方案,我只是在试探一个答案:)啊,我应该考虑一下子类化!谢谢你的建议!我很确定我只需要重写
create
方法,就是这样。只需要两行就行了!第一行:super(SessionStore,self).create()
第二行:self.set\u expiration(timezone.now()+timedelta(seconds=settings.SESSION\u COOKIE\u AGE))
我还没有对它进行彻底的测试,但从我所做的测试来看,它似乎有效。