python / expert
Snippet
Django Session Management with Custom Backend
Django's session framework is extensible and allows custom storage backends beyond the default database, cache, or file-based options. This implementation demonstrates a Redis-backed session store that provides sub-millisecond read/write operations, automatic expiration via TTL, and atomic save operations with CreateError handling for must_create scenarios. Custom backends are essential for high-traffic applications requiring horizontal scaling.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import jsonfrom django.contrib.sessions.backends.base import SessionBase, CreateErrorfrom django.db import transactionclass RedisSessionStore(SessionBase):engine = 'django.contrib.sessions'prefix = 'session:'def __init__(self, session_key=None):super().__init__(session_key)self._redis = self._get_redis_client()def _get_redis_client(self):import django.conf as confcfg = conf.settings.SESSION_ENGINE_CONFIGimport redisreturn redis.Redis(host=cfg.get('HOST', 'localhost'),port=cfg.get('PORT', 6379),db=cfg.get('DB', 0),password=cfg.get('PASSWORD', None))@propertydef key(self):return self._get_or_create_session_key()def _get_redis_key(self, key=None):return f"{self.prefix}{key or self._get_or_create_session_key()}"def load(self):data = self._redis.get(self._get_redis_key())return json.loads(data) if data else {}def exists(self, session_key):return self._redis.exists(self._get_redis_key(session_key)) > 0@transaction.atomicdef save(self, must_create=False):key = self._get_or_create_session_key()if must_create and self.exists(key):raise CreateErrordata = json.dumps(self._session)self._redis.setex(self._get_redis_key(key), self.get_expiry_age(), data)def delete(self, session_key=None):self._redis.delete(self._get_redis_key(session_key or self._session_key))
django
Breakdown
1
class RedisSessionStore(SessionBase):
Custom session store inheriting from Django's SessionBase abstract class
2
def load(self):
Retrieves session data from Redis, returns empty dict if missing
3
def exists(self, session_key):
Checks if session key exists in Redis using EXISTS command
4
@transaction.atomic
Ensures save operation is atomic to prevent partial writes
5
def save(self, must_create=False):
Persists session to Redis with expiration using SETEX command
6
self._redis.setex(..., self.get_expiry_age(), data)
SETEX sets value with expiration time in seconds (Redis built-in TTL)