django 将数据保存到会话而不增加其到期时间

django save data to session without increasing its expiry

基本上我想做这样的事情:

request.session['last_date'] = datetime.datetime.now()

没有 django 修改(增加)会话 expire_date(即,它应该保持原样)

我有SESSION_SAVE_EVERY_REQUEST = True

如上修改last_date时,session过期时间应该保持不变。然而,对于所有其他更改,到期时间应该更改。我不想将其设置为会话的全局策略。

当您想更改会话引擎的默认行为时,通常的做法是编写自定义会话后端。幸运的是,这不是很困难。我们将通过子类化 django.contrib.session.backends.db.SessionStore

来创建我们的

从 django.contrib.session.backends.db 将 SessionStore 导入为 DbStore

class SessionStore(DbStore):

    def load(self):
        try:
            self.current_session = self.model.objects.get(
                session_key=self.session_key,
                expire_date__gt=timezone.now()
            )
            return self.decode(s.session_data)
        except (self.model.DoesNotExist, SuspiciousOperation) as e:
            if isinstance(e, SuspiciousOperation):
                logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
                logger.warning(force_text(e))
            self._session_key = None
            return {}

    def create_model_instance(self, data):
        """
        Return a new instance of the session model object, which represents the
        current session state. Intended to be used for saving the session data
        to the database.
        """
        try:
            expiry = self.current_session.expire_date
        except AttributeError:
            expiry = None

        return self.model(
            session_key=self._get_or_create_session_key(),
            session_data=self.encode(data),
            expire_date=self.get_expiry_date(expiry=expiry),
        )

大部分代码来自 django.contrib,稍作修改。现在你所要做的就是通过修改 settings.py

告诉 django 使用我们新的会话存储
SESSION_ENGINE = 'myapp.session'

假设你把上面的代码放在一个名为session.py

的文件中

回复有问题的编辑

此代码展示了如何在不更改会话到期时间的情况下修改会话。现在您提到仅当更改 last_date 项时才需要此行为,请按如下方式进行修改;

        expiry = None

        try:
            if current_session.get('last_date') != date.get('last_date') :    
                expiry = self.current_session.expire_date
        except AttributeError:
            pass