| 1 | from django.conf import settings |
| 2 | from django.contrib.sessions.models import Session |
| 3 | from django.contrib.sessions.backends.base import SessionBase |
| 4 | from django.core.exceptions import SuspiciousOperation |
| 5 | from django.core.cache import cache |
| 6 | import datetime |
| 7 | |
| 8 | class SessionStore(SessionBase): |
| 9 | """ |
| 10 | Implements cached database session store |
| 11 | """ |
| 12 | def __init__(self, session_key=None): |
| 13 | super(SessionStore, self).__init__(session_key) |
| 14 | |
| 15 | def _get_cache_key(self): |
| 16 | return 'django_session_backend_cache_%s' % (self.session_key) |
| 17 | |
| 18 | def load(self): |
| 19 | try: |
| 20 | data = cache.get(self._get_cache_key(), None) |
| 21 | if data is None: |
| 22 | s = Session.objects.get( |
| 23 | session_key = self.session_key, |
| 24 | expire_date__gt=datetime.datetime.now() |
| 25 | ) |
| 26 | data = self.decode(s.session_data) |
| 27 | cache.set(self._get_cache_key(), data, settings.SESSION_COOKIE_AGE) |
| 28 | return data |
| 29 | except (Session.DoesNotExist, SuspiciousOperation): |
| 30 | # Create a new session_key for extra security. |
| 31 | self.session_key = self._get_new_session_key() |
| 32 | self._session_cache = {} |
| 33 | |
| 34 | # Save immediately to minimize collision |
| 35 | self.save() |
| 36 | return {} |
| 37 | |
| 38 | def exists(self, session_key): |
| 39 | try: |
| 40 | Session.objects.get(session_key=session_key) |
| 41 | except Session.DoesNotExist: |
| 42 | return False |
| 43 | return True |
| 44 | |
| 45 | def save(self): |
| 46 | cache.set(self._get_cache_key(), self._session, settings.SESSION_COOKIE_AGE) |
| 47 | Session.objects.create( |
| 48 | session_key = self.session_key, |
| 49 | session_data = self.encode(self._session), |
| 50 | expire_date = datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)) |
| 51 | |
| 52 | def delete(self, session_key): |
| 53 | try: |
| 54 | cache.delete(self._get_cache_key()) |
| 55 | Session.objects.get(session_key=session_key).delete() |
| 56 | except Session.DoesNotExist: |
| 57 | pass |