Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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)
@darkness51

This comment has been minimized.

Copy link

commented Nov 16, 2012

Hello Mike,

I am testing your session backend but I am receiving the following error:

AttributeError at /directlogin/
can't set attribute

You have idea what can cause this?

Best Regards

@pchartrand

This comment has been minimized.

Copy link

commented May 27, 2013

We are testing your backend for session data, with the intent of using multiple redis servers in a replicated environment. Any hints would be appreciated.

@muhammadsa

This comment has been minimized.

Copy link

commented Feb 24, 2014

you should get the below block out from the class's init to avoid calling it every time it is instantiated...to be called only one time.

self.redis = redis.Redis(
host = settings.SESSION_REDIS_HOST,
port = settings.SESSION_REDIS_PORT,
socket_timeout = settings.REDIS_SOCKET_TIMEOUT
)

@wachpwnski

This comment has been minimized.

Copy link

commented Mar 3, 2015

I think he wants a socket or each instance he creates, not to share sockets between all instances. That's why it is self.redis is assigned in the init func.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.