Skip to content

Instantly share code, notes, and snippets.

@sivy
Forked from mikeyk/redis_session_backend.py
Created April 11, 2012 01:53
Show Gist options
  • Save sivy/2356307 to your computer and use it in GitHub Desktop.
Save sivy/2356307 to your computer and use it in GitHub Desktop.
A redis backend for Django Sessions, tested on Django 1.3+
from django.contrib.sessions.backends.base import SessionBase, CreateError
from django.conf import settings
from django.utils.encoding import force_unicode
import redis
class SessionStore(SessionBase):
""" Redis store for sessions"""
def __init__(self, session_key=None):
self.redis = redis.Redis(
host = settings.SESSION_REDIS_HOST,
port = settings.SESSION_REDIS_PORT,
socket_timeout = settings.REDIS_SOCKET_TIMEOUT
)
super(SessionStore, self).__init__(session_key)
@classmethod
def _get_key_for_redis(self, session_key):
return 'sessionstore:%s' % session_key
def _redis_key(self):
return self.__class__._get_key_for_redis(self.session_key)
def load(self):
session_data = self.redis.get(self._redis_key())
if session_data is not None:
return self.decode(force_unicode(session_data))
else:
self.create()
return {}
def create(self):
max_attempts = 10
attempt = 0
while True:
self.session_key = self._get_new_session_key()
session_dict = self._get_session(no_load = True)
session_data = self.encode(session_dict)
was_created = self.redis.setnx(self._redis_key(),
session_data)
if was_created:
self.redis.expire(self._redis_key(),
settings.SESSION_COOKIE_AGE)
self.modified = True
self._session_cache = session_dict
return
else:
# extremely unlikely
if attempt == max_attempts:
raise CreateError
else:
attempt += 1
continue
def save(self, must_create=False):
if must_create:
self.create()
else:
encoded_data = self.encode(self._session)
self.redis.setex(self._redis_key(), encoded_data, settings.SESSION_COOKIE_AGE)
def exists(self, session_key):
return self.redis.exists(self.__class__._get_key_for_redis(session_key))
def delete(self, session_key=None):
to_delete = (session_key or self.session_key)
redis_key = self.__class__._get_key_for_redis(to_delete)
self.redis.delete(redis_key)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment