diff options
| author | Nick Pope <nick.pope@flightdataservices.com> | 2020-12-14 10:42:22 +0000 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-12-17 09:57:21 +0100 |
| commit | bb64b99b78a579cb2f6178011a4cf9366e634438 (patch) | |
| tree | 7c20092227eb3038ba7ca664112064bb16ed516a /django/core/cache/backends/base.py | |
| parent | d23dad5778b3610a5f870b4757ba628780924dd1 (diff) | |
Fixed #29867 -- Added support for storing None value in caches.
Many of the cache operations make use of the default argument to the
.get() operation to determine whether the key was found in the cache.
The default value of the default argument is None, so this results in
these operations assuming that None is not stored in the cache when it
actually is. Adding a sentinel object solves this issue.
Unfortunately the unmaintained python-memcached library does not support
a default argument to .get(), so the previous behavior is preserved for
the deprecated MemcachedCache backend.
Diffstat (limited to 'django/core/cache/backends/base.py')
| -rw-r--r-- | django/core/cache/backends/base.py | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py index 22b8397cac..1e2c7c9509 100644 --- a/django/core/cache/backends/base.py +++ b/django/core/cache/backends/base.py @@ -52,6 +52,8 @@ def get_key_func(key_func): class BaseCache: + _missing_key = object() + def __init__(self, params): timeout = params.get('timeout', params.get('TIMEOUT', 300)) if timeout is not None: @@ -151,8 +153,8 @@ class BaseCache: """ d = {} for k in keys: - val = self.get(k, version=version) - if val is not None: + val = self.get(k, self._missing_key, version=version) + if val is not self._missing_key: d[k] = val return d @@ -165,31 +167,29 @@ class BaseCache: Return the value of the key stored or retrieved. """ - val = self.get(key, version=version) - if val is None: + val = self.get(key, self._missing_key, version=version) + if val is self._missing_key: if callable(default): default = default() - if default is not None: - self.add(key, default, timeout=timeout, version=version) - # Fetch the value again to avoid a race condition if another - # caller added a value between the first get() and the add() - # above. - return self.get(key, default, version=version) + self.add(key, default, timeout=timeout, version=version) + # Fetch the value again to avoid a race condition if another caller + # added a value between the first get() and the add() above. + return self.get(key, default, version=version) return val def has_key(self, key, version=None): """ Return True if the key is in the cache and has not expired. """ - return self.get(key, version=version) is not None + return self.get(key, self._missing_key, version=version) is not self._missing_key def incr(self, key, delta=1, version=None): """ Add delta to value in the cache. If the key does not exist, raise a ValueError exception. """ - value = self.get(key, version=version) - if value is None: + value = self.get(key, self._missing_key, version=version) + if value is self._missing_key: raise ValueError("Key '%s' not found" % key) new_value = value + delta self.set(key, new_value, version=version) @@ -257,8 +257,8 @@ class BaseCache: if version is None: version = self.version - value = self.get(key, version=version) - if value is None: + value = self.get(key, self._missing_key, version=version) + if value is self._missing_key: raise ValueError("Key '%s' not found" % key) self.set(key, value, version=version + delta) |
