summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Tao <daniel.tao@gmail.com>2017-09-15 16:16:44 -0500
committerTim Graham <timograham@gmail.com>2017-10-10 09:35:52 -0400
commitdc112bf530fe2fc3b9be82bb7a6e3213c5f7fc11 (patch)
treee5d0949b922cef20deaafbb5ea9b145bb2fa0233
parentd3e115151eaf1d7ce8d6402563f9ff7dd2a72180 (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.py12
-rw-r--r--docs/releases/1.11.7.txt3
-rw-r--r--tests/cache/tests.py5
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)