Code

Ticket #5815: add_cache_clear_feature.diff

File add_cache_clear_feature.diff, 3.7 KB (added by k0001, 6 years ago)

adds per-view clear cache support

Line 
1Index: django/utils/cache.py
2===================================================================
3--- django/utils/cache.py       (revision 6603)
4+++ django/utils/cache.py       (working copy)
5@@ -158,18 +158,50 @@
6     cache as the pages themselves. If the cache ages some data out of the
7     cache, this just means that we have to build the response once to get at
8     the Vary header and so at the list of headers to use for the cache key.
9+   
10+    Also, another key (hashes) is added to the cache, to keep track of every
11+    page hash that matches the same request path.
12     """
13     if key_prefix is None:
14         key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
15     if cache_timeout is None:
16         cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
17-    cache_key = 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, iri_to_uri(request.path))
18+    header_key = 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, iri_to_uri(request.path))
19     if response.has_header('Vary'):
20         headerlist = ['HTTP_'+header.upper().replace('-', '_') for header in vary_delim_re.split(response['Vary'])]
21-        cache.set(cache_key, headerlist, cache_timeout)
22-        return _generate_cache_key(request, headerlist, key_prefix)
23     else:
24-        # if there is no Vary header, we still need a cache key
25-        # for the request.path
26-        cache.set(cache_key, [], cache_timeout)
27-        return _generate_cache_key(request, [], key_prefix)
28+        headerlist = []
29+
30+    cache.set(header_key, headerlist, cache_timeout)
31+    cache_key = _generate_cache_key(request, headerlist, key_prefix)
32+
33+    hashes_key = 'views.decorators.cache.cache_hashes.%s.%s' % (key_prefix, iri_to_uri(request.path))
34+    hashes = cache.get(hashes_key, [])
35+    page_hash = cache_key.split('.')[-1]
36+    if not page_hash in hashes:
37+        hashes.append(page_hash)
38+        cache.set(hashes_key, hashes, cache_timeout)
39+
40+    return cache_key
41+
42+def clear_cache_for_path(path, key_prefix=None):
43+    """
44+    Given a request path, every cache entry related to it gets deleted,
45+    specifically, the following keys get deleted:
46+        views.decorators.cache.cache_hashes.`key_prefix`.`path`
47+        views.decorators.cache.cache_header.`key_prefix`.`path`
48+        views.decorators.cache.cache_page.`key_prefix`.`path`.*
49+    """
50+    if key_prefix is None:
51+        key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
52+    hashes_key = 'views.decorators.cache.cache_hashes.%s.%s' % (key_prefix, iri_to_uri(path))
53+    hashes = cache.get(hashes_key, None)
54+    if hashes:
55+        for page_hash in hashes:
56+            page_key = 'views.decorators.cache.cache_page.%s.%s.%s' \
57+                           % (key_prefix, iri_to_uri(path), page_hash)
58+            cache.delete(page_key)
59+        header_key = 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, iri_to_uri(path))
60+        cache.delete(header_key)
61+    cache.delete(hashes_key)
62+
63Index: docs/cache.txt
64===================================================================
65--- docs/cache.txt      (revision 6603)
66+++ docs/cache.txt      (working copy)
67@@ -574,6 +574,21 @@
68 
69 .. _`Cache-Control spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
70 
71+Cache refreshing
72+================
73+
74+It is possible to clear the cache for an specific view, to achieve that, you
75+should tell your view's url path (and optionally, a key_prefix) to
76+``clear_cache_for_path(path, key_prefix=None)``.
77+
78+    from django.utils.cache import clear_cache_for_path
79+   
80+    # clear the all cached data for path '/blog/posts/2/'
81+    clear_cache_for_path('/blog/posts/2/')
82+   
83+Note that it will delete every page cached from matching this path, ``Vary`` headers
84+doesn't matter.
85+
86 Other optimizations
87 ===================
88