You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cache.py 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from django.conf import settings
  2. from django.contrib.sessions.backends.base import (
  3. CreateError, SessionBase, UpdateError,
  4. )
  5. from django.core.cache import caches
  6. KEY_PREFIX = "django.contrib.sessions.cache"
  7. class SessionStore(SessionBase):
  8. """
  9. A cache-based session store.
  10. """
  11. cache_key_prefix = KEY_PREFIX
  12. def __init__(self, session_key=None):
  13. self._cache = caches[settings.SESSION_CACHE_ALIAS]
  14. super().__init__(session_key)
  15. @property
  16. def cache_key(self):
  17. return self.cache_key_prefix + self._get_or_create_session_key()
  18. def load(self):
  19. try:
  20. session_data = self._cache.get(self.cache_key)
  21. except Exception:
  22. # Some backends (e.g. memcache) raise an exception on invalid
  23. # cache keys. If this happens, reset the session. See #17810.
  24. session_data = None
  25. if session_data is not None:
  26. return session_data
  27. self._session_key = None
  28. return {}
  29. def create(self):
  30. # Because a cache can fail silently (e.g. memcache), we don't know if
  31. # we are failing to create a new session because of a key collision or
  32. # because the cache is missing. So we try for a (large) number of times
  33. # and then raise an exception. That's the risk you shoulder if using
  34. # cache backing.
  35. for i in range(10000):
  36. self._session_key = self._get_new_session_key()
  37. try:
  38. self.save(must_create=True)
  39. except CreateError:
  40. continue
  41. self.modified = True
  42. return
  43. raise RuntimeError(
  44. "Unable to create a new session key. "
  45. "It is likely that the cache is unavailable.")
  46. def save(self, must_create=False):
  47. if self.session_key is None:
  48. return self.create()
  49. if must_create:
  50. func = self._cache.add
  51. elif self._cache.get(self.cache_key) is not None:
  52. func = self._cache.set
  53. else:
  54. raise UpdateError
  55. result = func(self.cache_key,
  56. self._get_session(no_load=must_create),
  57. self.get_expiry_age())
  58. if must_create and not result:
  59. raise CreateError
  60. def exists(self, session_key):
  61. return bool(session_key) and (self.cache_key_prefix + session_key) in self._cache
  62. def delete(self, session_key=None):
  63. if session_key is None:
  64. if self.session_key is None:
  65. return
  66. session_key = self.session_key
  67. self._cache.delete(self.cache_key_prefix + session_key)
  68. @classmethod
  69. def clear_expired(cls):
  70. pass