Index: django/core/cache/backends/base.py
===================================================================
--- django/core/cache/backends/base.py	(revision 7948)
+++ django/core/cache/backends/base.py	(working copy)
@@ -63,4 +63,29 @@
         """
         return self.get(key) is not None
 
+    def _incr_or_decr(self, key, delta=1):
+        '''
+        Increment or decrement a value in the cache.
+        '''
+        if key not in self:
+            raise ValueError, 'key not found %s' % key
+        new_value = self.get(key) + delta
+        self.set(key, new_value)
+        return new_value
+
+
+    def incr(self, key, delta=1):
+        """
+        Add delta to value in the cache. If the key does not exist, raise a 
+        ValueError exception.
+        """
+        return self._incr_or_decr(key, delta)
+
+    def decr(self, key, delta=1):
+        """
+        Subtract delta from value in the cache. If the key does not exist, raise
+        a ValueError exception.
+        """
+        return self._incr_or_decr(key, -delta)
+
     __contains__ = has_key
Index: django/core/cache/backends/dummy.py
===================================================================
--- django/core/cache/backends/dummy.py	(revision 7948)
+++ django/core/cache/backends/dummy.py	(working copy)
@@ -18,6 +18,12 @@
     def delete(self, *args, **kwargs):
         pass
 
+    def incr(self, key, delta=1):
+        raise NotImplementedException
+
+    def decr(self, key, delta=1):
+        raise NotImplementedException
+
     def get_many(self, *args, **kwargs):
         return {}
 
Index: django/core/cache/backends/memcached.py
===================================================================
--- django/core/cache/backends/memcached.py	(revision 7948)
+++ django/core/cache/backends/memcached.py	(working copy)
@@ -39,3 +39,9 @@
 
     def get_many(self, keys):
         return self._cache.get_multi(map(smart_str,keys))
+
+    def decr(self, key, delta=1):
+        return self._cache.decr(key, delta)
+
+    def incr(self, key, delta=1):
+        return self._cache.incr(key, delta)
Index: tests/regressiontests/cache/tests.py
===================================================================
--- tests/regressiontests/cache/tests.py	(revision 7948)
+++ tests/regressiontests/cache/tests.py	(working copy)
@@ -62,6 +62,22 @@
         self.assertEqual("hello2" in cache, True)
         self.assertEqual("goodbye2" in cache, False)
 
+    def test_incr(self):
+        cache.set('answer', 41)
+        self.assertEqual(cache.incr('answer'), 42)
+        self.assertEqual(cache.get('answer'), 42)
+        self.assertEqual(cache.incr('answer', 10), 52)
+        self.assertEqual(cache.get('answer'), 52)
+        self.assertRaises(ValueError, cache.incr, 'does_not_exist')
+
+    def test_decr(self):
+        cache.set('answer', 43)
+        self.assertEqual(cache.decr('answer'), 42)
+        self.assertEqual(cache.get('answer'), 42)
+        self.assertEqual(cache.decr('answer', 10), 32)
+        self.assertEqual(cache.get('answer'), 32)
+        self.assertRaises(ValueError, cache.decr, 'does_not_exist')
+
     def test_data_types(self):
         stuff = {
             'string'    : 'this is a string',
Index: docs/cache.txt
===================================================================
--- docs/cache.txt	(revision 7948)
+++ docs/cache.txt	(working copy)
@@ -394,6 +394,21 @@
     >>> cache.get('add_key')
     'Initial value'
 
+***New in Django development verison:** To increment or decrement a key that already
+exists, use the ``incr()`` or ``decr()`` methods, respectively. These methods are only
+atomic for the memecached backend. A dummy implementation is available for other cache
+backends, but ***these operations are not atomic for other cache backends.** Attempting 
+to increment or decrement a nonexistent key will trigger a ValueError exception. The
+result of incrementing or decrementing non-integer values is undefined (don't do that)::
+
+    >>> cache.set('num', 1)
+    >>> cache.incr('num')
+    2
+    >>> cache.incr('num', 10)
+    12
+    >>> cache.decr('num', 5)
+    7
+
 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)::
