How Sessions Bridge Stateless HTTP
HTTP itself is stateless — each request is independent with no memory of prior ones — so Django's session framework simulates continuity by storing a dictionary-like object (request.session) server-side, associated with a randomly generated session key sent to the browser as a cookie (sessionid by default). On each request, SessionMiddleware reads that cookie, loads the matching session data from the configured backend, and makes it available as request.session for the view to read or modify.
Cricket analogy: HTTP requests without sessions are like each ball being bowled with no memory of the previous one; a session is like the umpire's running tally that carries state (runs, wickets, overs) forward across every delivery.
Session Backends
SESSION_ENGINE controls where session data actually lives: the default django.contrib.sessions.backends.db stores it in a database table (django_session), backends.cache uses your configured cache (fast, but volatile if the cache is cleared), backends.cached_db does both for speed with a durable fallback, and backends.signed_cookies stores the session data itself inside the cookie, cryptographically signed but not encrypted, so it must never hold sensitive plaintext data.
Cricket analogy: backends.db is like a ground's permanent official scorebook (durable, slower to update), while signed_cookies is like a spectator's own handwritten scorecard carried in their pocket (fast, portable, but visible to them if unencrypted).
Reading, Writing, and Expiring Session Data
You read and write session data like a normal dict: request.session['cart_id'] = 42, and request.session.get('cart_id'). By default sessions expire when the browser closes (SESSION_EXPIRE_AT_BROWSER_CLOSE) or after SESSION_COOKIE_AGE seconds (two weeks by default); calling request.session.set_expiry(0) forces browser-close expiry for a single session, while set_expiry(1209600) sets an explicit duration in seconds for that session only.
Cricket analogy: Setting session expiry is like a rain-rule cutoff time set for a match — set_expiry(0) is like a match that ends the moment the covers come off (a short, immediate boundary), while a longer expiry is like a scheduled five-day Test with a fixed end date.
def add_to_cart(request, product_id):
cart = request.session.get('cart', {})
cart[str(product_id)] = cart.get(str(product_id), 0) + 1
request.session['cart'] = cart
# Mark modified if mutating a nested structure in-place
request.session.modified = True
return redirect('cart-detail')
def remember_me_login(request):
if request.POST.get('remember_me'):
request.session.set_expiry(1209600) # 2 weeks
else:
request.session.set_expiry(0) # expires on browser close
return redirect('dashboard')Mutating a nested object already stored in the session (like cart.update(...) on a dict already saved) won't be detected automatically by Django's session save logic. Set request.session.modified = True explicitly whenever you mutate a session value in place rather than reassigning it.
signed_cookies session storage is signed (tamper-evident) using SECRET_KEY but not encrypted — anyone with browser access can read the cookie's contents, so never store sensitive plaintext values like raw passwords in a session backed by signed_cookies.
- Sessions simulate continuity over stateless HTTP using a server-side store keyed by a browser cookie.
- SessionMiddleware loads request.session on every request based on the sessionid cookie.
- SESSION_ENGINE chooses the backend: db, cache, cached_db, or signed_cookies.
- request.session behaves like a dictionary for reading and writing per-visitor data.
- set_expiry() controls how long an individual session remains valid.
- In-place mutation of nested session values requires request.session.modified = True.
- signed_cookies data is tamper-evident but not encrypted, so avoid storing sensitive plaintext there.
Practice what you learned
1. Why does Django need a session framework at all?
2. What does SESSION_ENGINE control?
3. Why is signed_cookies storage described as tamper-evident but not confidential?
4. When must you manually set request.session.modified = True?
5. What does request.session.set_expiry(0) do?
Was this page helpful?
You May Also Like
User Authentication in Django
Django's auth framework provides a User model, session-based login/logout, password hashing, and decorators to protect views — all ready to use out of the box.
Permissions and Groups
Django's permission system lets you gate actions per-model or per-object using auto-generated permissions, custom permissions, and reusable Groups that bundle permissions together.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics