Refs #29708 -- Made SessionBase store expiry as string.

This commit is contained in:
Adam Johnson 2021-11-29 17:22:23 +00:00 committed by Mariusz Felisiak
parent c6cb5a0277
commit 436862787c
3 changed files with 23 additions and 24 deletions

View File

@ -210,8 +210,10 @@ class SessionBase:
if not expiry: # Checks both None and 0 cases
return self.get_session_cookie_age()
if not isinstance(expiry, datetime):
if not isinstance(expiry, (datetime, str)):
return expiry
if isinstance(expiry, str):
expiry = datetime.fromisoformat(expiry)
delta = expiry - modification
return delta.days * 86400 + delta.seconds
@ -233,6 +235,8 @@ class SessionBase:
if isinstance(expiry, datetime):
return expiry
elif isinstance(expiry, str):
return datetime.fromisoformat(expiry)
expiry = expiry or self.get_session_cookie_age()
return modification + timedelta(seconds=expiry)
@ -260,6 +264,8 @@ class SessionBase:
return
if isinstance(value, timedelta):
value = timezone.now() + value
if isinstance(value, datetime):
value = value.isoformat()
self['_session_expiry'] = value
def get_expire_at_browser_close(self):

View File

@ -258,10 +258,8 @@ You can edit it multiple times.
``request.session.set_expiry(300)`` would make the session expire
in 5 minutes.
* If ``value`` is a ``datetime`` or ``timedelta`` object, the
session will expire at that specific date/time. Note that ``datetime``
and ``timedelta`` values are only serializable if you are using the
:class:`~django.contrib.sessions.serializers.PickleSerializer`.
* If ``value`` is a ``datetime`` or ``timedelta`` object, the session
will expire at that specific date/time.
* If ``value`` is ``0``, the user's session cookie will expire
when the user's web browser is closed.

View File

@ -333,25 +333,20 @@ class SessionTestsMixin:
self.assertEqual(self.session.decode(encoded), {})
def test_actual_expiry(self):
# this doesn't work with JSONSerializer (serializing timedelta)
with override_settings(SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer'):
self.session = self.backend() # reinitialize after overriding settings
# Regression test for #19200
old_session_key = None
new_session_key = None
try:
self.session['foo'] = 'bar'
self.session.set_expiry(-timedelta(seconds=10))
self.session.save()
old_session_key = self.session.session_key
# With an expiry date in the past, the session expires instantly.
new_session = self.backend(self.session.session_key)
new_session_key = new_session.session_key
self.assertNotIn('foo', new_session)
finally:
self.session.delete(old_session_key)
self.session.delete(new_session_key)
old_session_key = None
new_session_key = None
try:
self.session['foo'] = 'bar'
self.session.set_expiry(-timedelta(seconds=10))
self.session.save()
old_session_key = self.session.session_key
# With an expiry date in the past, the session expires instantly.
new_session = self.backend(self.session.session_key)
new_session_key = new_session.session_key
self.assertNotIn('foo', new_session)
finally:
self.session.delete(old_session_key)
self.session.delete(new_session_key)
def test_session_load_does_not_create_record(self):
"""