1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

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 if not expiry: # Checks both None and 0 cases
return self.get_session_cookie_age() return self.get_session_cookie_age()
if not isinstance(expiry, datetime): if not isinstance(expiry, (datetime, str)):
return expiry return expiry
if isinstance(expiry, str):
expiry = datetime.fromisoformat(expiry)
delta = expiry - modification delta = expiry - modification
return delta.days * 86400 + delta.seconds return delta.days * 86400 + delta.seconds
@ -233,6 +235,8 @@ class SessionBase:
if isinstance(expiry, datetime): if isinstance(expiry, datetime):
return expiry return expiry
elif isinstance(expiry, str):
return datetime.fromisoformat(expiry)
expiry = expiry or self.get_session_cookie_age() expiry = expiry or self.get_session_cookie_age()
return modification + timedelta(seconds=expiry) return modification + timedelta(seconds=expiry)
@ -260,6 +264,8 @@ class SessionBase:
return return
if isinstance(value, timedelta): if isinstance(value, timedelta):
value = timezone.now() + value value = timezone.now() + value
if isinstance(value, datetime):
value = value.isoformat()
self['_session_expiry'] = value self['_session_expiry'] = value
def get_expire_at_browser_close(self): 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 ``request.session.set_expiry(300)`` would make the session expire
in 5 minutes. in 5 minutes.
* If ``value`` is a ``datetime`` or ``timedelta`` object, the * If ``value`` is a ``datetime`` or ``timedelta`` object, the session
session will expire at that specific date/time. Note that ``datetime`` will expire at that specific date/time.
and ``timedelta`` values are only serializable if you are using the
:class:`~django.contrib.sessions.serializers.PickleSerializer`.
* If ``value`` is ``0``, the user's session cookie will expire * If ``value`` is ``0``, the user's session cookie will expire
when the user's web browser is closed. when the user's web browser is closed.

View File

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