diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index 06e8952..d680e82 100644
a
|
b
|
class BaseCache(object):
|
125 | 125 | d[k] = val |
126 | 126 | return d |
127 | 127 | |
| 128 | def get_or_set(self, key, default, timeout=None, version=None): |
| 129 | """ |
| 130 | Fetch a given key from the cache. If the key does not exist, |
| 131 | the default value is added to cache. If the default value is callable |
| 132 | the key will be set to return of default value. |
| 133 | Returns a tuple of (object, is_set), where is_set is a boolean |
| 134 | specifying whether the key is new in the cache |
| 135 | """ |
| 136 | val, is_set = self.get(key, version=version), False |
| 137 | if val is None: |
| 138 | if callable(default): |
| 139 | val = default() |
| 140 | else: |
| 141 | val = default |
| 142 | is_set = self.add(key, val, timeout, version) |
| 143 | if not is_set: |
| 144 | val, is_set = self.get(key, version=version), False |
| 145 | if val is None: |
| 146 | raise ValueError("get_or_set failed on Key '%s'" % key) |
| 147 | return val, is_set |
| 148 | |
128 | 149 | def has_key(self, key, version=None): |
129 | 150 | """ |
130 | 151 | Returns True if the key is in the cache and has not expired. |
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index 2f95c33..1a79f2e 100644
a
|
b
|
of key-value pairs::
|
744 | 744 | |
745 | 745 | Like ``cache.set()``, ``set_many()`` takes an optional ``timeout`` parameter. |
746 | 746 | |
| 747 | In cases where you may wish to use either a cached value or create a new cached value |
| 748 | there is the ``get_or_set()`` method. It takes the same parameters as get but rather than simply return |
| 749 | the default value, the default is set as the new cache value for that key. If the default value is callable |
| 750 | it's return value will be stored. Returns a tuple of (object, is_set), where is_set is a boolean |
| 751 | specifying whether the key is new in the cache |
| 752 | |
| 753 | >>> cache.get_or_set('a',1) |
| 754 | 1, True |
| 755 | >>> cache.get('a') |
| 756 | 1 |
| 757 | >>> cache.set('b',1) |
| 758 | >>> cache.get_or_set('b',2) |
| 759 | 1, False |
| 760 | .. versionadded:: 1.5 |
| 761 | |
747 | 762 | You can delete keys explicitly with ``delete()``. This is an easy way of |
748 | 763 | clearing the cache for a particular object:: |
749 | 764 | |
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index de27bc9..7a692e2 100644
a
|
b
|
class BaseCacheTests(object):
|
228 | 228 | self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {'a' : 'a', 'c' : 'c', 'd' : 'd'}) |
229 | 229 | self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {'a' : 'a', 'b' : 'b'}) |
230 | 230 | |
| 231 | def test_get_or_set(self): |
| 232 | #Test when no value is set |
| 233 | val, is_set = self.cache.get_or_set('a', 'a') |
| 234 | self.assertEqual(is_set, True) |
| 235 | self.assertEqual(val, 'a') |
| 236 | self.assertEqual(self.cache.get('a'), 'a') |
| 237 | |
| 238 | #Test an existing value |
| 239 | self.cache.set('b', 'b') |
| 240 | self.assertEqual(self.cache.get_or_set('b', 'c'), ('b', False)) |
| 241 | |
| 242 | #Test a callable |
| 243 | def cache_val(): |
| 244 | return 'c' |
| 245 | |
| 246 | val, is_set = self.cache.get_or_set('c', cache_val) |
| 247 | self.assertEqual(is_set, True) |
| 248 | self.assertEqual(val, 'c') |
| 249 | self.assertEqual(self.cache.get('c'), 'c') |
| 250 | |
231 | 251 | def test_delete(self): |
232 | 252 | # Cache keys can be deleted |
233 | 253 | self.cache.set("key1", "spam") |