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)