diff options
| author | Daniel Tao <daniel.tao@gmail.com> | 2017-09-15 16:16:44 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-10-10 09:35:52 -0400 |
| commit | dc112bf530fe2fc3b9be82bb7a6e3213c5f7fc11 (patch) | |
| tree | e5d0949b922cef20deaafbb5ea9b145bb2fa0233 | |
| parent | d3e115151eaf1d7ce8d6402563f9ff7dd2a72180 (diff) | |
[2.0.x] Fixed #28601 -- Prevented cache.get_or_set() from caching None if default is a callable that returns None.
Backport of 4d60261b2a77460b4c127c3d832518b95e11a0ac from master
| -rw-r--r-- | django/core/cache/backends/base.py | 12 | ||||
| -rw-r--r-- | docs/releases/1.11.7.txt | 3 | ||||
| -rw-r--r-- | tests/cache/tests.py | 5 |
3 files changed, 14 insertions, 6 deletions
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py index aaf34c042e..cf0df7cc68 100644 --- a/django/core/cache/backends/base.py +++ b/django/core/cache/backends/base.py @@ -155,13 +155,15 @@ class BaseCache: Return the value of the key stored or retrieved. """ val = self.get(key, version=version) - if val is None and default is not None: + if val is None: if callable(default): default = default() - 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) + 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) return val def has_key(self, key, version=None): diff --git a/docs/releases/1.11.7.txt b/docs/releases/1.11.7.txt index 41d144e742..61f0d6d012 100644 --- a/docs/releases/1.11.7.txt +++ b/docs/releases/1.11.7.txt @@ -9,4 +9,5 @@ Django 1.11.7 fixes several bugs in 1.11.6. Bugfixes ======== -* ... +* Prevented ``cache.get_or_set()`` from caching ``None`` if the ``default`` + argument is a callable that returns ``None`` (:ticket:`28601`). diff --git a/tests/cache/tests.py b/tests/cache/tests.py index e093dc842d..0549d790bc 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -926,6 +926,11 @@ class BaseCacheTests: self.assertEqual(cache.get_or_set('mykey', my_callable), 'value') self.assertEqual(cache.get_or_set('mykey', my_callable()), 'value') + def test_get_or_set_callable_returning_none(self): + self.assertIsNone(cache.get_or_set('mykey', lambda: None)) + # Previous get_or_set() doesn't store None in the cache. + self.assertEqual(cache.get('mykey', 'default'), 'default') + def test_get_or_set_version(self): msg = "get_or_set() missing 1 required positional argument: 'default'" cache.get_or_set('brian', 1979, version=2) |
