Loading django/core/cache/backends/base.py +21 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,27 @@ class BaseCache(object): d[k] = val return d def get_or_set(self, key, default=None, timeout=DEFAULT_TIMEOUT, version=None): """ Fetch a given key from the cache. If the key does not exist, the key is added and set to the default value. The default value can also be any callable. If timeout is given, that timeout will be used for the key; otherwise the default cache timeout will be used. Returns the value of the key stored or retrieved on success, False on error. """ if default is None: raise ValueError('You need to specify a value.') val = self.get(key, version=version) if val is None: if callable(default): default = default() val = self.add(key, default, timeout=timeout, version=version) if val: return self.get(key, version=version) return val def has_key(self, key, version=None): """ Returns True if the key is in the cache and has not expired. Loading docs/releases/1.9.txt +2 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,8 @@ Minor features Cache ^^^^^ * ... * ``django.core.cache.backends.base.BaseCache`` now has a ``get_or_set()`` method. Email ^^^^^ Loading docs/topics/cache.txt +19 −0 Original line number Diff line number Diff line Loading @@ -778,6 +778,25 @@ If you need to know whether ``add()`` stored a value in the cache, you can check the return value. It will return ``True`` if the value was stored, ``False`` otherwise. If you want to get a key's value or set a value if the key isn't in the cache, there is the ``get_or_set()`` method. It takes the same parameters as ``get()`` but the default is set as the new cache value for that key, rather than simply returned:: >>> cache.get('my_new_key') # returns None >>> cache.get_or_set('my_new_key', 'my new value', 100) 'my new value' You can also pass any callable as a *default* value:: >>> import datetime >>> cache.get_or_set('some-timestamp-key', datetime.datetime.now) datetime.datetime(2014, 12, 11, 0, 15, 49, 457920) .. versionchanged:: 1.9 The ``get_or_set()`` method was added. There's also a ``get_many()`` interface that only hits the cache once. ``get_many()`` returns a dictionary with all the keys you asked for that actually exist in the cache (and haven't expired):: Loading tests/cache/tests.py +22 −0 Original line number Diff line number Diff line Loading @@ -884,6 +884,28 @@ class BaseCacheTests(object): with self.assertRaises(pickle.PickleError): cache.set('unpickable', Unpickable()) def test_get_or_set(self): self.assertIsNone(cache.get('projector')) self.assertEqual(cache.get_or_set('projector', 42), 42) self.assertEqual(cache.get('projector'), 42) def test_get_or_set_callable(self): def my_callable(): return 'value' self.assertEqual(cache.get_or_set('mykey', my_callable), 'value') def test_get_or_set_version(self): cache.get_or_set('brian', 1979, version=2) with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): cache.get_or_set('brian') with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): cache.get_or_set('brian', version=1) self.assertIsNone(cache.get('brian', version=1)) self.assertEqual(cache.get_or_set('brian', 42, version=1), 42) self.assertEqual(cache.get_or_set('brian', 1979, version=2), 1979) self.assertIsNone(cache.get('brian', version=3)) @override_settings(CACHES=caches_setting_for_tests( BACKEND='django.core.cache.backends.db.DatabaseCache', Loading Loading
django/core/cache/backends/base.py +21 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,27 @@ class BaseCache(object): d[k] = val return d def get_or_set(self, key, default=None, timeout=DEFAULT_TIMEOUT, version=None): """ Fetch a given key from the cache. If the key does not exist, the key is added and set to the default value. The default value can also be any callable. If timeout is given, that timeout will be used for the key; otherwise the default cache timeout will be used. Returns the value of the key stored or retrieved on success, False on error. """ if default is None: raise ValueError('You need to specify a value.') val = self.get(key, version=version) if val is None: if callable(default): default = default() val = self.add(key, default, timeout=timeout, version=version) if val: return self.get(key, version=version) return val def has_key(self, key, version=None): """ Returns True if the key is in the cache and has not expired. Loading
docs/releases/1.9.txt +2 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,8 @@ Minor features Cache ^^^^^ * ... * ``django.core.cache.backends.base.BaseCache`` now has a ``get_or_set()`` method. Email ^^^^^ Loading
docs/topics/cache.txt +19 −0 Original line number Diff line number Diff line Loading @@ -778,6 +778,25 @@ If you need to know whether ``add()`` stored a value in the cache, you can check the return value. It will return ``True`` if the value was stored, ``False`` otherwise. If you want to get a key's value or set a value if the key isn't in the cache, there is the ``get_or_set()`` method. It takes the same parameters as ``get()`` but the default is set as the new cache value for that key, rather than simply returned:: >>> cache.get('my_new_key') # returns None >>> cache.get_or_set('my_new_key', 'my new value', 100) 'my new value' You can also pass any callable as a *default* value:: >>> import datetime >>> cache.get_or_set('some-timestamp-key', datetime.datetime.now) datetime.datetime(2014, 12, 11, 0, 15, 49, 457920) .. versionchanged:: 1.9 The ``get_or_set()`` method was added. There's also a ``get_many()`` interface that only hits the cache once. ``get_many()`` returns a dictionary with all the keys you asked for that actually exist in the cache (and haven't expired):: Loading
tests/cache/tests.py +22 −0 Original line number Diff line number Diff line Loading @@ -884,6 +884,28 @@ class BaseCacheTests(object): with self.assertRaises(pickle.PickleError): cache.set('unpickable', Unpickable()) def test_get_or_set(self): self.assertIsNone(cache.get('projector')) self.assertEqual(cache.get_or_set('projector', 42), 42) self.assertEqual(cache.get('projector'), 42) def test_get_or_set_callable(self): def my_callable(): return 'value' self.assertEqual(cache.get_or_set('mykey', my_callable), 'value') def test_get_or_set_version(self): cache.get_or_set('brian', 1979, version=2) with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): cache.get_or_set('brian') with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): cache.get_or_set('brian', version=1) self.assertIsNone(cache.get('brian', version=1)) self.assertEqual(cache.get_or_set('brian', 42, version=1), 42) self.assertEqual(cache.get_or_set('brian', 1979, version=2), 1979) self.assertIsNone(cache.get('brian', version=3)) @override_settings(CACHES=caches_setting_for_tests( BACKEND='django.core.cache.backends.db.DatabaseCache', Loading