mirror of
https://github.com/django/django.git
synced 2025-08-03 10:34:04 +00:00
Fixed #22634 -- Made the database-backed session backends more extensible.
Introduced an AbstractBaseSession model and hooks providing the option of overriding the model class used by the session store and the session store class used by the model.
This commit is contained in:
parent
956df84a61
commit
22bb548900
12 changed files with 370 additions and 78 deletions
|
@ -34,6 +34,8 @@ from django.utils import six, timezone
|
|||
from django.utils.encoding import force_text
|
||||
from django.utils.six.moves import http_cookies
|
||||
|
||||
from .custom_db_backend import SessionStore as CustomDatabaseSession
|
||||
|
||||
|
||||
class SessionTestsMixin(object):
|
||||
# This does not inherit from TestCase to avoid any tests being run with this
|
||||
|
@ -355,6 +357,11 @@ class SessionTestsMixin(object):
|
|||
class DatabaseSessionTests(SessionTestsMixin, TestCase):
|
||||
|
||||
backend = DatabaseSession
|
||||
session_engine = 'django.contrib.sessions.backends.db'
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
return self.backend.get_model_class()
|
||||
|
||||
def test_session_str(self):
|
||||
"Session repr should be the session key."
|
||||
|
@ -362,7 +369,7 @@ class DatabaseSessionTests(SessionTestsMixin, TestCase):
|
|||
self.session.save()
|
||||
|
||||
session_key = self.session.session_key
|
||||
s = Session.objects.get(session_key=session_key)
|
||||
s = self.model.objects.get(session_key=session_key)
|
||||
|
||||
self.assertEqual(force_text(s), session_key)
|
||||
|
||||
|
@ -374,7 +381,7 @@ class DatabaseSessionTests(SessionTestsMixin, TestCase):
|
|||
self.session['x'] = 1
|
||||
self.session.save()
|
||||
|
||||
s = Session.objects.get(session_key=self.session.session_key)
|
||||
s = self.model.objects.get(session_key=self.session.session_key)
|
||||
|
||||
self.assertEqual(s.get_decoded(), {'x': 1})
|
||||
|
||||
|
@ -386,19 +393,18 @@ class DatabaseSessionTests(SessionTestsMixin, TestCase):
|
|||
self.session['y'] = 1
|
||||
self.session.save()
|
||||
|
||||
s = Session.objects.get(session_key=self.session.session_key)
|
||||
s = self.model.objects.get(session_key=self.session.session_key)
|
||||
# Change it
|
||||
Session.objects.save(s.session_key, {'y': 2}, s.expire_date)
|
||||
self.model.objects.save(s.session_key, {'y': 2}, s.expire_date)
|
||||
# Clear cache, so that it will be retrieved from DB
|
||||
del self.session._session_cache
|
||||
self.assertEqual(self.session['y'], 2)
|
||||
|
||||
@override_settings(SESSION_ENGINE="django.contrib.sessions.backends.db")
|
||||
def test_clearsessions_command(self):
|
||||
"""
|
||||
Test clearsessions command for clearing expired sessions.
|
||||
"""
|
||||
self.assertEqual(0, Session.objects.count())
|
||||
self.assertEqual(0, self.model.objects.count())
|
||||
|
||||
# One object in the future
|
||||
self.session['foo'] = 'bar'
|
||||
|
@ -412,10 +418,11 @@ class DatabaseSessionTests(SessionTestsMixin, TestCase):
|
|||
other_session.save()
|
||||
|
||||
# Two sessions are in the database before clearsessions...
|
||||
self.assertEqual(2, Session.objects.count())
|
||||
management.call_command('clearsessions')
|
||||
self.assertEqual(2, self.model.objects.count())
|
||||
with override_settings(SESSION_ENGINE=self.session_engine):
|
||||
management.call_command('clearsessions')
|
||||
# ... and one is deleted.
|
||||
self.assertEqual(1, Session.objects.count())
|
||||
self.assertEqual(1, self.model.objects.count())
|
||||
|
||||
|
||||
@override_settings(USE_TZ=True)
|
||||
|
@ -423,6 +430,29 @@ class DatabaseSessionWithTimeZoneTests(DatabaseSessionTests):
|
|||
pass
|
||||
|
||||
|
||||
class CustomDatabaseSessionTests(DatabaseSessionTests):
|
||||
backend = CustomDatabaseSession
|
||||
session_engine = 'sessions_tests.custom_db_backend'
|
||||
|
||||
def test_extra_session_field(self):
|
||||
# Set the account ID to be picked up by a custom session storage
|
||||
# and saved to a custom session model database column.
|
||||
self.session['_auth_user_id'] = 42
|
||||
self.session.save()
|
||||
|
||||
# Make sure that the customized create_model_instance() was called.
|
||||
s = self.model.objects.get(session_key=self.session.session_key)
|
||||
self.assertEqual(s.account_id, 42)
|
||||
|
||||
# Make the session "anonymous".
|
||||
self.session.pop('_auth_user_id')
|
||||
self.session.save()
|
||||
|
||||
# Make sure that save() on an existing session did the right job.
|
||||
s = self.model.objects.get(session_key=self.session.session_key)
|
||||
self.assertEqual(s.account_id, None)
|
||||
|
||||
|
||||
class CacheDBSessionTests(SessionTestsMixin, TestCase):
|
||||
|
||||
backend = CacheDBSession
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue