|
1 import datetime |
|
2 from django.conf import settings |
|
3 from django.contrib.sessions.models import Session |
|
4 from django.contrib.sessions.backends.base import SessionBase, CreateError |
|
5 from django.core.exceptions import SuspiciousOperation |
|
6 from django.db import IntegrityError, transaction, router |
|
7 from django.utils.encoding import force_unicode |
|
8 |
|
9 class SessionStore(SessionBase): |
|
10 """ |
|
11 Implements database session store. |
|
12 """ |
|
13 def __init__(self, session_key=None): |
|
14 super(SessionStore, self).__init__(session_key) |
|
15 |
|
16 def load(self): |
|
17 try: |
|
18 s = Session.objects.get( |
|
19 session_key = self.session_key, |
|
20 expire_date__gt=datetime.datetime.now() |
|
21 ) |
|
22 return self.decode(force_unicode(s.session_data)) |
|
23 except (Session.DoesNotExist, SuspiciousOperation): |
|
24 self.create() |
|
25 return {} |
|
26 |
|
27 def exists(self, session_key): |
|
28 try: |
|
29 Session.objects.get(session_key=session_key) |
|
30 except Session.DoesNotExist: |
|
31 return False |
|
32 return True |
|
33 |
|
34 def create(self): |
|
35 while True: |
|
36 self.session_key = self._get_new_session_key() |
|
37 try: |
|
38 # Save immediately to ensure we have a unique entry in the |
|
39 # database. |
|
40 self.save(must_create=True) |
|
41 except CreateError: |
|
42 # Key wasn't unique. Try again. |
|
43 continue |
|
44 self.modified = True |
|
45 self._session_cache = {} |
|
46 return |
|
47 |
|
48 def save(self, must_create=False): |
|
49 """ |
|
50 Saves the current session data to the database. If 'must_create' is |
|
51 True, a database error will be raised if the saving operation doesn't |
|
52 create a *new* entry (as opposed to possibly updating an existing |
|
53 entry). |
|
54 """ |
|
55 obj = Session( |
|
56 session_key = self.session_key, |
|
57 session_data = self.encode(self._get_session(no_load=must_create)), |
|
58 expire_date = self.get_expiry_date() |
|
59 ) |
|
60 using = router.db_for_write(Session, instance=obj) |
|
61 sid = transaction.savepoint(using=using) |
|
62 try: |
|
63 obj.save(force_insert=must_create, using=using) |
|
64 except IntegrityError: |
|
65 if must_create: |
|
66 transaction.savepoint_rollback(sid, using=using) |
|
67 raise CreateError |
|
68 raise |
|
69 |
|
70 def delete(self, session_key=None): |
|
71 if session_key is None: |
|
72 if self._session_key is None: |
|
73 return |
|
74 session_key = self._session_key |
|
75 try: |
|
76 Session.objects.get(session_key=session_key).delete() |
|
77 except Session.DoesNotExist: |
|
78 pass |