diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py index 58e166d655623..cb5fe06045f5c 100644 --- a/django/core/cache/backends/base.py +++ b/django/core/cache/backends/base.py @@ -19,6 +19,8 @@ def add(self, key, value, timeout=None): Set a value in the cache if the key does not already exist. If timeout is given, that timeout will be used for the key; otherwise the default cache timeout will be used. + + Returns True if the value was stored, False otherwise. """ raise NotImplementedError diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index d54677057f87f..d2b422af8350f 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -38,7 +38,7 @@ def get(self, key, default=None): return pickle.loads(base64.decodestring(row[1])) def set(self, key, value, timeout=None): - return self._base_set('set', key, value, timeout) + self._base_set('set', key, value, timeout) def add(self, key, value, timeout=None): return self._base_set('add', key, value, timeout) @@ -62,9 +62,10 @@ def _base_set(self, mode, key, value, timeout=None): cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)]) except DatabaseError: # To be threadsafe, updates/inserts are allowed to fail silently - pass + return False else: transaction.commit_unless_managed() + return True def delete(self, key): cursor = connection.cursor() diff --git a/django/core/cache/backends/dummy.py b/django/core/cache/backends/dummy.py index 3ff7e1c1b9150..e479703f75d58 100644 --- a/django/core/cache/backends/dummy.py +++ b/django/core/cache/backends/dummy.py @@ -7,7 +7,7 @@ def __init__(self, *args, **kwargs): pass def add(self, *args, **kwargs): - pass + return True def get(self, key, default=None): return default diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 0ad586d477f7b..181197a8d7b3a 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -32,9 +32,10 @@ def __init__(self, dir, params): def add(self, key, value, timeout=None): if self.has_key(key): - return None + return False self.set(key, value, timeout) + return True def get(self, key, default=None): fname = self._key_to_file(key) diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py index 053e0735f70d2..15a169dc37870 100644 --- a/django/core/cache/backends/locmem.py +++ b/django/core/cache/backends/locmem.py @@ -36,8 +36,10 @@ def add(self, key, value, timeout=None): if exp is None or exp <= time.time(): try: self._set(key, pickle.dumps(value), timeout) + return True except pickle.PickleError: pass + return False finally: self._lock.writer_leaves() diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 096cec0ee02fa..e25d7a10fbf31 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -17,7 +17,7 @@ def __init__(self, server, params): self._cache = memcache.Client(server.split(';')) def add(self, key, value, timeout=0): - self._cache.add(key.encode('ascii', 'ignore'), value, timeout or self.default_timeout) + return self._cache.add(key.encode('ascii', 'ignore'), value, timeout or self.default_timeout) def get(self, key, default=None): val = self._cache.get(smart_str(key)) diff --git a/docs/cache.txt b/docs/cache.txt index bf5b876959e65..5748e8b85bce8 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -410,9 +410,13 @@ it will not attempt to update the cache if the key specified is already present: >>> cache.get('add_key') 'Initial value' -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):: +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. + +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):: >>> cache.set('a', 1) >>> cache.set('b', 2) diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py index 78c32288b6a10..81b78433a8a0b 100644 --- a/tests/regressiontests/cache/tests.py +++ b/tests/regressiontests/cache/tests.py @@ -31,7 +31,8 @@ def test_simple(self): def test_add(self): # test add (only add if key isn't already in cache) cache.add("addkey1", "value") - cache.add("addkey1", "newvalue") + result = cache.add("addkey1", "newvalue") + self.assertEqual(result, False) self.assertEqual(cache.get("addkey1"), "value") def test_non_existent(self):