summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorSergey Kolosov <m17.admin@gmail.com>2014-05-16 18:18:34 +0200
committerTim Graham <timograham@gmail.com>2015-08-27 15:00:09 -0400
commit22bb548900146832459deaefa880660c17a51516 (patch)
tree1b37547e692234b180bc0688f672c15714541108 /docs
parent956df84a613d4b9a92c979e46557243d288282c8 (diff)
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.
Diffstat (limited to 'docs')
-rw-r--r--docs/releases/1.9.txt5
-rw-r--r--docs/topics/http/sessions.txt177
2 files changed, 179 insertions, 3 deletions
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 1a5c488d0f..35b45ead43 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -254,7 +254,10 @@ Minor features
:mod:`django.contrib.sessions`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-* ...
+* The session model and ``SessionStore`` classes for the ``db`` and
+ ``cached_db`` backends are refactored to allow a custom database session
+ backend to build upon them. See
+ :ref:`extending-database-backed-session-engines` for more details.
:mod:`django.contrib.sitemaps`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 3a825f28cb..da9e5ef567 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -514,8 +514,10 @@ access sessions using the normal Django database API::
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)
-Note that you'll need to call ``get_decoded()`` to get the session dictionary.
-This is necessary because the dictionary is stored in an encoded format::
+Note that you'll need to call
+:meth:`~base_session.AbstractBaseSession.get_decoded()` to get the session
+dictionary. This is necessary because the dictionary is stored in an encoded
+format::
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
@@ -670,6 +672,177 @@ Technical details
* Django only sends a cookie if it needs to. If you don't set any session
data, it won't send a session cookie.
+The ``SessionStore`` object
+---------------------------
+
+When working with sessions internally, Django uses a session store object from
+the corresponding session engine. By convention, the session store object class
+is named ``SessionStore`` and is located in the module designated by
+:setting:`SESSION_ENGINE`.
+
+All ``SessionStore`` classes available in Django inherit from
+:class:`~backends.base.SessionBase` and implement data manipulation methods,
+namely:
+
+* ``exists()``
+* ``create()``
+* ``save()``
+* ``delete()``
+* ``load()``
+* :meth:`~backends.base.SessionBase.clear_expired`
+
+In order to build a custom session engine or to customize an existing one, you
+may create a new class inheriting from :class:`~backends.base.SessionBase` or
+any other existing ``SessionStore`` class.
+
+Extending most of the session engines is quite straightforward, but doing so
+with database-backed session engines generally requires some extra effort (see
+the next section for details).
+
+.. _extending-database-backed-session-engines:
+
+Extending database-backed session engines
+=========================================
+
+.. versionadded:: 1.9
+
+Creating a custom database-backed session engine built upon those included in
+Django (namely ``db`` and ``cached_db``) may be done by inheriting
+:class:`~base_session.AbstractBaseSession` and either ``SessionStore`` class.
+
+``AbstractBaseSession`` and ``BaseSessionManager`` are importable from
+``django.contrib.sessions.base_session`` so that they can be imported without
+including ``django.contrib.sessions`` in :setting:`INSTALLED_APPS`.
+
+.. class:: base_session.AbstractBaseSession
+
+ .. versionadded:: 1.9
+
+ The abstract base session model.
+
+ .. attribute:: session_key
+
+ Primary key. The field itself may contain up to 40 characters. The
+ current implementation generates a 32-character string (a random
+ sequence of digits and lowercase ASCII letters).
+
+ .. attribute:: session_data
+
+ A string containing an encoded and serialized session dictionary.
+
+ .. attribute:: expire_date
+
+ A datetime designating when the session expires.
+
+ Expired sessions are not available to a user, however, they may still
+ be stored in the database until the :djadmin:`clearsessions` management
+ command is run.
+
+ .. classmethod:: get_session_store_class()
+
+ Returns a session store class to be used with this session model.
+
+ .. method:: get_decoded()
+
+ Returns decoded session data.
+
+ Decoding is performed by the session store class.
+
+You can also customize the model manager by subclassing
+:class:`~django.contrib.sessions.base_session.BaseSessionManager`:
+
+.. class:: base_session.BaseSessionManager
+
+ .. versionadded:: 1.9
+
+ .. method:: encode(session_dict)
+
+ Returns the given session dictionary serialized and encoded as a string.
+
+ Encoding is performed by the session store class tied to a model class.
+
+ .. method:: save(session_key, session_dict, expire_date)
+
+ Saves session data for a provided session key, or deletes the session
+ in case the data is empty.
+
+Customization of ``SessionStore`` classes is achieved by overriding methods
+and properties described below:
+
+.. class:: backends.db.SessionStore
+
+ Implements database-backed session store.
+
+ .. classmethod:: get_model_class()
+
+ .. versionadded:: 1.9
+
+ Override this method to return a custom session model if you need one.
+
+ .. method:: create_model_instance(data)
+
+ .. versionadded:: 1.9
+
+ Returns a new instance of the session model object, which represents
+ the current session state.
+
+ Overriding this method provides the ability to modify session model
+ data before it's saved to database.
+
+.. class:: backends.cached_db.SessionStore
+
+ Implements cached database-backed session store.
+
+ .. attribute:: cache_key_prefix
+
+ .. versionadded:: 1.9
+
+ A prefix added to a session key to build a cache key string.
+
+Example
+-------
+
+The example below shows a custom database-backed session engine that includes
+an additional database column to store an account ID (thus providing an option
+to query the database for all active sessions for an account)::
+
+ from django.contrib.sessions.backends.db import SessionStore as DBStore
+ from django.contrib.sessions.base_session import AbstractBaseSession
+ from django.db import models
+
+ class CustomSession(AbstractBaseSession):
+ account_id = models.IntegerField(null=True, db_index=True)
+
+ class Meta:
+ app_label = 'mysessions'
+
+ @classmethod
+ def get_session_store_class(cls):
+ return SessionStore
+
+ class SessionStore(DBStore):
+ @classmethod
+ def get_model_class(cls):
+ return CustomSession
+
+ def create_model_instance(self, data):
+ obj = super(SessionStore, self).create_model_instance(data)
+ try:
+ account_id = int(data.get('_auth_user_id'))
+ except (ValueError, TypeError):
+ account_id = None
+ obj.account_id = account_id
+ return obj
+
+If you are migrating from the Django's built-in ``cached_db`` session store to
+a custom one based on ``cached_db``, you should override the cache key prefix
+in order to prevent a namespace clash::
+
+ class SessionStore(CachedDBStore):
+ cache_key_prefix = 'mysessions.custom_cached_db_backend'
+
+ # ...
+
Session IDs in URLs
===================