Django Sessions

Imagine you had to log back in to a website every time you navigated to another page, or your favorite websites forgot all of your settings and you had to enter them again each time you visited?

Modern websites could not provide the usability and convenience we are used to without some way of remembering who you are and your previous activities on the website. HTTP is, by design, stateless – there is no persistence between one request and the next, and there is no way the server can tell whether successive requests come from the same person.

This lack of state is managed using sessions, which are a semi-permanent, two-way communication between your browser and the web server. When you visit a modern website, in the majority of cases, the web server will use an anonymous session to keep track of data relevant to your visit. The session is called anonymous because the web server can only record what you did, not who you are.

We have all experienced this when we have returned to an eCommerce site at a later date and found the items we put in the cart are still there, despite not having provided any personal details.
Sessions are most often persisted using the often maligned, but rarely understood cookie. Like all other web frameworks, Django also uses cookies, but does so in a more clever and secure manner, as you will see.

Django provides full support for anonymous sessions. The session framework lets you store and retrieve arbitrary data on a per-site-visitor basis. It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID – not the data itself (unless you’re using the cookie based backend); a more secure way of implementing cookies than some other frameworks.

Enabling Sessions

Sessions are implemented via a piece of middleware. The default settings.py created by django-admin startproject has SessionMiddleware activated. To enable session functionality, edit the MIDDLEWARE_CLASSES setting and make sure it contains 'django.contrib.sessions.middleware.SessionMiddleware'.

If you don’t want to use sessions, you might as well remove the SessionMiddleware line from MIDDLEWARE_CLASSES and 'django.contrib.sessions' from your INSTALLED_APPS. It’ll save you a small bit of overhead.

Configuring The Session Engine

By default, Django stores sessions in your database (using the model django.contrib.sessions.models.Session). Though this is convenient, in some setups it’s faster to store session data elsewhere, so Django can be configured to store session data on your file system or in your cache.

Using Database-Backed Sessions

If you want to use a database-backed session, you need to add 'django.contrib.sessions' to your INSTALLED_APPS setting. Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.

Using Cached Sessions

For better performance, you may want to use a cache-based session backend. To store session data using Django’s cache system, you’ll first need to make sure you’ve configured your cache; see the cache documentation for details.

If you have multiple caches defined in CACHES, Django will use the default cache. To use another cache, set SESSION_CACHE_ALIAS to the name of that cache. Once your cache is configured, you’ve got two choices for how to store data in the cache:

  1. Set SESSION_ENGINE to "django.contrib.sessions.backends.cache" for a simple caching session store. Session data will be stored directly in your cache. However, session data may not be persistent: cached data can be evicted if the cache fills up or if the cache server is restarted.
  2. For persistent, cached data, set SESSION_ENGINE to "django.contrib.sessions.backends.cached_db". This uses a write-through cache – every write to the cache will also be written to the database. Session reads only use the database if the data is not already in the cache.

Both session stores are quite fast, but the simple cache is faster because it disregards persistence. In most cases, the cached_db backend will be fast enough, but if you need that last bit of performance, and are willing to let session data be expunged from time to time, the cache backend is for you. If you use the cached_db session backend, you also need to follow the configuration instructions for the using database-backed sessions.

Using File-Based Sessions

To use file-based sessions, set the SESSION_ENGINE setting to "django.contrib.sessions.backends.file". You might also want to set the SESSION_FILE_PATH setting (which defaults to output from tempfile.gettempdir(), most likely /tmp) to control where Django stores session files. Be sure to check that your Web server has permissions to read and write to this location.

To use cookies-based sessions, set the SESSION_ENGINE setting to "django.contrib.sessions.backends.signed_cookies". The session data will be stored using Django’s tools for cryptographic signing and the SECRET_KEY setting.

It’s recommended to leave the SESSION_COOKIE_HTTPONLY setting on True to prevent access to the stored data from JavaScript.

Finally, assuming the above warnings have not discouraged you from using cookie based sessions: the size of a cookie can also have an impact on the speed of your site.