1 | diff --git a/django/middleware/cache.py b/django/middleware/cache.py
|
---|
2 | index 34bf0ca..049238e 100644
|
---|
3 | --- a/django/middleware/cache.py
|
---|
4 | +++ b/django/middleware/cache.py
|
---|
5 | @@ -48,12 +48,72 @@ More details about how the caching works:
|
---|
6 |
|
---|
7 | """
|
---|
8 |
|
---|
9 | +import hashlib
|
---|
10 | +
|
---|
11 | +from django.utils.encoding import iri_to_uri
|
---|
12 | from django.conf import settings
|
---|
13 | from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
|
---|
14 | -from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
|
---|
15 | +from django.utils.cache import patch_response_headers, get_max_age, cc_delim_re
|
---|
16 | +from django.utils.timezone import get_current_timezone_name
|
---|
17 | +from django.utils.translation import get_language
|
---|
18 |
|
---|
19 | +class TwoPartCacheMiddlewareBase(object):
|
---|
20 | + @classmethod
|
---|
21 | + def get_cache_key(cls, request, key_prefix=None, method='GET', cache=None):
|
---|
22 | + """
|
---|
23 | + Returns a cache key based on the request path and query. It can be used
|
---|
24 | + in the request phase because it pulls the list of headers to take into
|
---|
25 | + account from the global path registry and uses those to build a cache key
|
---|
26 | + to check against.
|
---|
27 |
|
---|
28 | -class UpdateCacheMiddleware(object):
|
---|
29 | + If there is no headerlist stored, the page needs to be rebuilt, so this
|
---|
30 | + function returns None.
|
---|
31 | + """
|
---|
32 | + if key_prefix is None:
|
---|
33 | + key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
---|
34 | + cache_key = cls._generate_cache_header_key(key_prefix, request)
|
---|
35 | + if cache is None:
|
---|
36 | + cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
---|
37 | + headerlist = cache.get(cache_key, None)
|
---|
38 | + if headerlist is not None:
|
---|
39 | + return cls._generate_cache_key(request, method, headerlist, key_prefix)
|
---|
40 | + else:
|
---|
41 | + return None
|
---|
42 | +
|
---|
43 | + @classmethod
|
---|
44 | + def _i18n_cache_key_suffix(cls, request, cache_key):
|
---|
45 | + """If necessary, adds the current locale or time zone to the cache key."""
|
---|
46 | + if settings.USE_I18N or settings.USE_L10N:
|
---|
47 | + # first check if LocaleMiddleware or another middleware added
|
---|
48 | + # LANGUAGE_CODE to request, then fall back to the active language
|
---|
49 | + # which in turn can also fall back to settings.LANGUAGE_CODE
|
---|
50 | + cache_key += '.%s' % getattr(request, 'LANGUAGE_CODE', get_language())
|
---|
51 | + if settings.USE_TZ:
|
---|
52 | + cache_key += '.%s' % get_current_timezone_name()
|
---|
53 | + return cache_key
|
---|
54 | +
|
---|
55 | + @classmethod
|
---|
56 | + def _generate_cache_key(cls, request, method, headerlist, key_prefix):
|
---|
57 | + """Returns a cache key from the headers given in the header list."""
|
---|
58 | + ctx = hashlib.md5()
|
---|
59 | + for header in headerlist:
|
---|
60 | + value = request.META.get(header, None)
|
---|
61 | + if value is not None:
|
---|
62 | + ctx.update(value)
|
---|
63 | + path = hashlib.md5(iri_to_uri(request.get_full_path()))
|
---|
64 | + cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
|
---|
65 | + key_prefix, method, path.hexdigest(), ctx.hexdigest())
|
---|
66 | + return cls._i18n_cache_key_suffix(request, cache_key)
|
---|
67 | +
|
---|
68 | + @classmethod
|
---|
69 | + def _generate_cache_header_key(cls, key_prefix, request):
|
---|
70 | + """Returns a cache key for the header cache."""
|
---|
71 | + path = hashlib.md5(iri_to_uri(request.get_full_path()))
|
---|
72 | + cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
|
---|
73 | + key_prefix, path.hexdigest())
|
---|
74 | + return cls._i18n_cache_key_suffix(request, cache_key)
|
---|
75 | +
|
---|
76 | +class UpdateCacheMiddleware(TwoPartCacheMiddlewareBase):
|
---|
77 | """
|
---|
78 | Response-phase cache middleware that updates the cache if the response is
|
---|
79 | cacheable.
|
---|
80 | @@ -88,6 +148,38 @@ class UpdateCacheMiddleware(object):
|
---|
81 | return False
|
---|
82 | return True
|
---|
83 |
|
---|
84 | + @classmethod
|
---|
85 | + def learn_cache_key(cls, request, response, cache_timeout=None, key_prefix=None, cache=None):
|
---|
86 | + """
|
---|
87 | + Learns what headers to take into account for some request path from the
|
---|
88 | + response object. It stores those headers in a global path registry so that
|
---|
89 | + later access to that path will know what headers to take into account
|
---|
90 | + without building the response object itself. The headers are named in the
|
---|
91 | + Vary header of the response, but we want to prevent response generation.
|
---|
92 | +
|
---|
93 | + The list of headers to use for cache key generation is stored in the same
|
---|
94 | + cache as the pages themselves. If the cache ages some data out of the
|
---|
95 | + cache, this just means that we have to build the response once to get at
|
---|
96 | + the Vary header and so at the list of headers to use for the cache key.
|
---|
97 | + """
|
---|
98 | + if key_prefix is None:
|
---|
99 | + key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
---|
100 | + if cache_timeout is None:
|
---|
101 | + cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
|
---|
102 | + cache_key = cls._generate_cache_header_key(key_prefix, request)
|
---|
103 | + if cache is None:
|
---|
104 | + cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
---|
105 | + if response.has_header('Vary'):
|
---|
106 | + headerlist = ['HTTP_'+header.upper().replace('-', '_')
|
---|
107 | + for header in cc_delim_re.split(response['Vary'])]
|
---|
108 | + cache.set(cache_key, headerlist, cache_timeout)
|
---|
109 | + return cls._generate_cache_key(request, request.method, headerlist, key_prefix)
|
---|
110 | + else:
|
---|
111 | + # if there is no Vary header, we still need a cache key
|
---|
112 | + # for the request.get_full_path()
|
---|
113 | + cache.set(cache_key, [], cache_timeout)
|
---|
114 | + return cls._generate_cache_key(request, request.method, [], key_prefix)
|
---|
115 | +
|
---|
116 | def process_response(self, request, response):
|
---|
117 | """Sets the cache, if needed."""
|
---|
118 | if not self._should_update_cache(request, response):
|
---|
119 | @@ -106,7 +198,7 @@ class UpdateCacheMiddleware(object):
|
---|
120 | return response
|
---|
121 | patch_response_headers(response, timeout)
|
---|
122 | if timeout:
|
---|
123 | - cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
|
---|
124 | + cache_key = self.learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
|
---|
125 | if hasattr(response, 'render') and callable(response.render):
|
---|
126 | response.add_post_render_callback(
|
---|
127 | lambda r: self.cache.set(cache_key, r, timeout)
|
---|
128 | @@ -115,7 +207,7 @@ class UpdateCacheMiddleware(object):
|
---|
129 | self.cache.set(cache_key, response, timeout)
|
---|
130 | return response
|
---|
131 |
|
---|
132 | -class FetchFromCacheMiddleware(object):
|
---|
133 | +class FetchFromCacheMiddleware(TwoPartCacheMiddlewareBase):
|
---|
134 | """
|
---|
135 | Request-phase cache middleware that fetches a page from the cache.
|
---|
136 |
|
---|
137 | @@ -140,14 +232,14 @@ class FetchFromCacheMiddleware(object):
|
---|
138 | return None # Don't bother checking the cache.
|
---|
139 |
|
---|
140 | # try and get the cached GET response
|
---|
141 | - cache_key = get_cache_key(request, self.key_prefix, 'GET', cache=self.cache)
|
---|
142 | + cache_key = self.get_cache_key(request, self.key_prefix, 'GET', cache=self.cache)
|
---|
143 | if cache_key is None:
|
---|
144 | request._cache_update_cache = True
|
---|
145 | return None # No cache information available, need to rebuild.
|
---|
146 | response = self.cache.get(cache_key, None)
|
---|
147 | # if it wasn't found and we are looking for a HEAD, try looking just for that
|
---|
148 | if response is None and request.method == 'HEAD':
|
---|
149 | - cache_key = get_cache_key(request, self.key_prefix, 'HEAD', cache=self.cache)
|
---|
150 | + cache_key = self.get_cache_key(request, self.key_prefix, 'HEAD', cache=self.cache)
|
---|
151 | response = self.cache.get(cache_key, None)
|
---|
152 |
|
---|
153 | if response is None:
|
---|
154 | diff --git a/django/utils/cache.py b/django/utils/cache.py
|
---|
155 | index 1015c2f..9448aae 100644
|
---|
156 | --- a/django/utils/cache.py
|
---|
157 | +++ b/django/utils/cache.py
|
---|
158 | @@ -23,10 +23,8 @@ import time
|
---|
159 |
|
---|
160 | from django.conf import settings
|
---|
161 | from django.core.cache import get_cache
|
---|
162 | -from django.utils.encoding import smart_str, iri_to_uri
|
---|
163 | +from django.utils.encoding import smart_str
|
---|
164 | from django.utils.http import http_date
|
---|
165 | -from django.utils.timezone import get_current_timezone_name
|
---|
166 | -from django.utils.translation import get_language
|
---|
167 |
|
---|
168 | cc_delim_re = re.compile(r'\s*,\s*')
|
---|
169 |
|
---|
170 | @@ -122,12 +120,6 @@ def patch_response_headers(response, cache_timeout=None):
|
---|
171 | response['Expires'] = http_date(time.time() + cache_timeout)
|
---|
172 | patch_cache_control(response, max_age=cache_timeout)
|
---|
173 |
|
---|
174 | -def add_never_cache_headers(response):
|
---|
175 | - """
|
---|
176 | - Adds headers to a response to indicate that a page should never be cached.
|
---|
177 | - """
|
---|
178 | - patch_response_headers(response, cache_timeout=-1)
|
---|
179 | -
|
---|
180 | def patch_vary_headers(response, newheaders):
|
---|
181 | """
|
---|
182 | Adds (or updates) the "Vary" header in the given HttpResponse object.
|
---|
183 | @@ -157,88 +149,6 @@ def has_vary_header(response, header_query):
|
---|
184 | existing_headers = set([header.lower() for header in vary_headers])
|
---|
185 | return header_query.lower() in existing_headers
|
---|
186 |
|
---|
187 | -def _i18n_cache_key_suffix(request, cache_key):
|
---|
188 | - """If necessary, adds the current locale or time zone to the cache key."""
|
---|
189 | - if settings.USE_I18N or settings.USE_L10N:
|
---|
190 | - # first check if LocaleMiddleware or another middleware added
|
---|
191 | - # LANGUAGE_CODE to request, then fall back to the active language
|
---|
192 | - # which in turn can also fall back to settings.LANGUAGE_CODE
|
---|
193 | - cache_key += '.%s' % getattr(request, 'LANGUAGE_CODE', get_language())
|
---|
194 | - if settings.USE_TZ:
|
---|
195 | - cache_key += '.%s' % get_current_timezone_name()
|
---|
196 | - return cache_key
|
---|
197 | -
|
---|
198 | -def _generate_cache_key(request, method, headerlist, key_prefix):
|
---|
199 | - """Returns a cache key from the headers given in the header list."""
|
---|
200 | - ctx = hashlib.md5()
|
---|
201 | - for header in headerlist:
|
---|
202 | - value = request.META.get(header, None)
|
---|
203 | - if value is not None:
|
---|
204 | - ctx.update(value)
|
---|
205 | - path = hashlib.md5(iri_to_uri(request.get_full_path()))
|
---|
206 | - cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
|
---|
207 | - key_prefix, method, path.hexdigest(), ctx.hexdigest())
|
---|
208 | - return _i18n_cache_key_suffix(request, cache_key)
|
---|
209 | -
|
---|
210 | -def _generate_cache_header_key(key_prefix, request):
|
---|
211 | - """Returns a cache key for the header cache."""
|
---|
212 | - path = hashlib.md5(iri_to_uri(request.get_full_path()))
|
---|
213 | - cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
|
---|
214 | - key_prefix, path.hexdigest())
|
---|
215 | - return _i18n_cache_key_suffix(request, cache_key)
|
---|
216 | -
|
---|
217 | -def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
---|
218 | - """
|
---|
219 | - Returns a cache key based on the request path and query. It can be used
|
---|
220 | - in the request phase because it pulls the list of headers to take into
|
---|
221 | - account from the global path registry and uses those to build a cache key
|
---|
222 | - to check against.
|
---|
223 | -
|
---|
224 | - If there is no headerlist stored, the page needs to be rebuilt, so this
|
---|
225 | - function returns None.
|
---|
226 | - """
|
---|
227 | - if key_prefix is None:
|
---|
228 | - key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
---|
229 | - cache_key = _generate_cache_header_key(key_prefix, request)
|
---|
230 | - if cache is None:
|
---|
231 | - cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
---|
232 | - headerlist = cache.get(cache_key, None)
|
---|
233 | - if headerlist is not None:
|
---|
234 | - return _generate_cache_key(request, method, headerlist, key_prefix)
|
---|
235 | - else:
|
---|
236 | - return None
|
---|
237 | -
|
---|
238 | -def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None):
|
---|
239 | - """
|
---|
240 | - Learns what headers to take into account for some request path from the
|
---|
241 | - response object. It stores those headers in a global path registry so that
|
---|
242 | - later access to that path will know what headers to take into account
|
---|
243 | - without building the response object itself. The headers are named in the
|
---|
244 | - Vary header of the response, but we want to prevent response generation.
|
---|
245 | -
|
---|
246 | - The list of headers to use for cache key generation is stored in the same
|
---|
247 | - cache as the pages themselves. If the cache ages some data out of the
|
---|
248 | - cache, this just means that we have to build the response once to get at
|
---|
249 | - the Vary header and so at the list of headers to use for the cache key.
|
---|
250 | - """
|
---|
251 | - if key_prefix is None:
|
---|
252 | - key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
---|
253 | - if cache_timeout is None:
|
---|
254 | - cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
|
---|
255 | - cache_key = _generate_cache_header_key(key_prefix, request)
|
---|
256 | - if cache is None:
|
---|
257 | - cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
|
---|
258 | - if response.has_header('Vary'):
|
---|
259 | - headerlist = ['HTTP_'+header.upper().replace('-', '_')
|
---|
260 | - for header in cc_delim_re.split(response['Vary'])]
|
---|
261 | - cache.set(cache_key, headerlist, cache_timeout)
|
---|
262 | - return _generate_cache_key(request, request.method, headerlist, key_prefix)
|
---|
263 | - else:
|
---|
264 | - # if there is no Vary header, we still need a cache key
|
---|
265 | - # for the request.get_full_path()
|
---|
266 | - cache.set(cache_key, [], cache_timeout)
|
---|
267 | - return _generate_cache_key(request, request.method, [], key_prefix)
|
---|
268 | -
|
---|
269 |
|
---|
270 | def _to_tuple(s):
|
---|
271 | t = s.split('=',1)
|
---|
272 | diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py
|
---|
273 | index a39cc54..2847e05 100644
|
---|
274 | --- a/django/views/decorators/cache.py
|
---|
275 | +++ b/django/views/decorators/cache.py
|
---|
276 | @@ -1,6 +1,6 @@
|
---|
277 | from functools import wraps
|
---|
278 | from django.utils.decorators import decorator_from_middleware_with_args, available_attrs
|
---|
279 | -from django.utils.cache import patch_cache_control, add_never_cache_headers
|
---|
280 | +from django.utils.cache import patch_cache_control, patch_response_headers
|
---|
281 | from django.middleware.cache import CacheMiddleware
|
---|
282 |
|
---|
283 |
|
---|
284 | @@ -86,6 +86,6 @@ def never_cache(view_func):
|
---|
285 | @wraps(view_func, assigned=available_attrs(view_func))
|
---|
286 | def _wrapped_view_func(request, *args, **kwargs):
|
---|
287 | response = view_func(request, *args, **kwargs)
|
---|
288 | - add_never_cache_headers(response)
|
---|
289 | + patch_response_headers(response, cache_timeout=0)
|
---|
290 | return response
|
---|
291 | return _wrapped_view_func
|
---|
292 | diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
|
---|
293 | index 307588c..ea13421 100644
|
---|
294 | --- a/tests/regressiontests/cache/tests.py
|
---|
295 | +++ b/tests/regressiontests/cache/tests.py
|
---|
296 | @@ -19,15 +19,15 @@ from django.core.cache.backends.base import (CacheKeyWarning,
|
---|
297 | from django.db import router
|
---|
298 | from django.http import HttpResponse, HttpRequest, QueryDict
|
---|
299 | from django.middleware.cache import (FetchFromCacheMiddleware,
|
---|
300 | - UpdateCacheMiddleware, CacheMiddleware)
|
---|
301 | + UpdateCacheMiddleware, CacheMiddleware, TwoPartCacheMiddlewareBase)
|
---|
302 | from django.template import Template
|
---|
303 | from django.template.response import TemplateResponse
|
---|
304 | from django.test import TestCase, TransactionTestCase, RequestFactory
|
---|
305 | from django.test.utils import (get_warnings_state, restore_warnings_state,
|
---|
306 | override_settings)
|
---|
307 | from django.utils import timezone, translation, unittest
|
---|
308 | -from django.utils.cache import (patch_vary_headers, get_cache_key,
|
---|
309 | - learn_cache_key, patch_cache_control, patch_response_headers)
|
---|
310 | +from django.utils.cache import (patch_vary_headers,
|
---|
311 | + patch_cache_control, patch_response_headers)
|
---|
312 | from django.views.decorators.cache import cache_page
|
---|
313 |
|
---|
314 | from .models import Poll, expensive_calculation
|
---|
315 | @@ -998,22 +998,11 @@ class CacheUtils(TestCase):
|
---|
316 | """TestCase for django.utils.cache functions."""
|
---|
317 |
|
---|
318 | def setUp(self):
|
---|
319 | - self.path = '/cache/test/'
|
---|
320 | self.cache = get_cache('default')
|
---|
321 |
|
---|
322 | def tearDown(self):
|
---|
323 | self.cache.clear()
|
---|
324 |
|
---|
325 | - def _get_request(self, path, method='GET'):
|
---|
326 | - request = HttpRequest()
|
---|
327 | - request.META = {
|
---|
328 | - 'SERVER_NAME': 'testserver',
|
---|
329 | - 'SERVER_PORT': 80,
|
---|
330 | - }
|
---|
331 | - request.method = method
|
---|
332 | - request.path = request.path_info = "/cache/%s" % path
|
---|
333 | - return request
|
---|
334 | -
|
---|
335 | def test_patch_vary_headers(self):
|
---|
336 | headers = (
|
---|
337 | # Initial vary, new headers, resulting vary.
|
---|
338 | @@ -1034,37 +1023,6 @@ class CacheUtils(TestCase):
|
---|
339 | patch_vary_headers(response, newheaders)
|
---|
340 | self.assertEqual(response['Vary'], resulting_vary)
|
---|
341 |
|
---|
342 | - def test_get_cache_key(self):
|
---|
343 | - request = self._get_request(self.path)
|
---|
344 | - response = HttpResponse()
|
---|
345 | - key_prefix = 'localprefix'
|
---|
346 | - # Expect None if no headers have been set yet.
|
---|
347 | - self.assertEqual(get_cache_key(request), None)
|
---|
348 | - # Set headers to an empty list.
|
---|
349 | - learn_cache_key(request, response)
|
---|
350 | - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
351 | - # Verify that a specified key_prefix is taken into account.
|
---|
352 | - learn_cache_key(request, response, key_prefix=key_prefix)
|
---|
353 | - self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
354 | -
|
---|
355 | - def test_get_cache_key_with_query(self):
|
---|
356 | - request = self._get_request(self.path + '?test=1')
|
---|
357 | - response = HttpResponse()
|
---|
358 | - # Expect None if no headers have been set yet.
|
---|
359 | - self.assertEqual(get_cache_key(request), None)
|
---|
360 | - # Set headers to an empty list.
|
---|
361 | - learn_cache_key(request, response)
|
---|
362 | - # Verify that the querystring is taken into account.
|
---|
363 | - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.bd889c5a59603af44333ed21504db3cd.d41d8cd98f00b204e9800998ecf8427e')
|
---|
364 | -
|
---|
365 | - def test_learn_cache_key(self):
|
---|
366 | - request = self._get_request(self.path, 'HEAD')
|
---|
367 | - response = HttpResponse()
|
---|
368 | - response['Vary'] = 'Pony'
|
---|
369 | - # Make sure that the Vary header is added to the key hash
|
---|
370 | - learn_cache_key(request, response)
|
---|
371 | - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
372 | -
|
---|
373 | def test_patch_cache_control(self):
|
---|
374 | tests = (
|
---|
375 | # Initial Cache-Control, kwargs to patch_cache_control, expected Cache-Control parts
|
---|
376 | @@ -1342,6 +1300,7 @@ class CacheMiddlewareTest(TestCase):
|
---|
377 |
|
---|
378 | def setUp(self):
|
---|
379 | self.factory = RequestFactory()
|
---|
380 | + self.path = '/cache/test/'
|
---|
381 | self.default_cache = get_cache('default')
|
---|
382 | self.other_cache = get_cache('other')
|
---|
383 |
|
---|
384 | @@ -1381,6 +1340,48 @@ class CacheMiddlewareTest(TestCase):
|
---|
385 | self.assertEqual(as_view_decorator_with_custom.cache_alias, 'other')
|
---|
386 | self.assertEqual(as_view_decorator_with_custom.cache_anonymous_only, True)
|
---|
387 |
|
---|
388 | + def _get_request(self, path, method='GET'):
|
---|
389 | + request = HttpRequest()
|
---|
390 | + request.META = {
|
---|
391 | + 'SERVER_NAME': 'testserver',
|
---|
392 | + 'SERVER_PORT': 80,
|
---|
393 | + }
|
---|
394 | + request.method = method
|
---|
395 | + request.path = request.path_info = "/cache/%s" % path
|
---|
396 | + return request
|
---|
397 | +
|
---|
398 | + def test_get_cache_key(self):
|
---|
399 | + request = self._get_request(self.path)
|
---|
400 | + response = HttpResponse()
|
---|
401 | + key_prefix = 'localprefix'
|
---|
402 | + # Expect None if no headers have been set yet.
|
---|
403 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), None)
|
---|
404 | + # Set headers to an empty list.
|
---|
405 | + UpdateCacheMiddleware.learn_cache_key(request, response)
|
---|
406 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
407 | + # Verify that a specified key_prefix is taken into account.
|
---|
408 | + UpdateCacheMiddleware.learn_cache_key(request, response, key_prefix=key_prefix)
|
---|
409 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
410 | +
|
---|
411 | + def test_get_cache_key_with_query(self):
|
---|
412 | + request = self._get_request(self.path + '?test=1')
|
---|
413 | + response = HttpResponse()
|
---|
414 | + # Expect None if no headers have been set yet.
|
---|
415 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), None)
|
---|
416 | + # Set headers to an empty list.
|
---|
417 | + UpdateCacheMiddleware.learn_cache_key(request, response)
|
---|
418 | + # Verify that the querystring is taken into account.
|
---|
419 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.bd889c5a59603af44333ed21504db3cd.d41d8cd98f00b204e9800998ecf8427e')
|
---|
420 | +
|
---|
421 | + def test_learn_cache_key(self):
|
---|
422 | + request = self._get_request(self.path, 'HEAD')
|
---|
423 | + response = HttpResponse()
|
---|
424 | + response['Vary'] = 'Pony'
|
---|
425 | + # Make sure that the Vary header is added to the key hash
|
---|
426 | + UpdateCacheMiddleware.learn_cache_key(request, response)
|
---|
427 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
428 | +
|
---|
429 | +
|
---|
430 | def test_middleware(self):
|
---|
431 | middleware = CacheMiddleware()
|
---|
432 | prefix_middleware = CacheMiddleware(key_prefix='prefix1')
|
---|
433 | @@ -1624,23 +1625,23 @@ class TestWithTemplateResponse(TestCase):
|
---|
434 | response = TemplateResponse(HttpResponse(), Template("This is a test"))
|
---|
435 | key_prefix = 'localprefix'
|
---|
436 | # Expect None if no headers have been set yet.
|
---|
437 | - self.assertEqual(get_cache_key(request), None)
|
---|
438 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), None)
|
---|
439 | # Set headers to an empty list.
|
---|
440 | - learn_cache_key(request, response)
|
---|
441 | - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
442 | + UpdateCacheMiddleware.learn_cache_key(request, response)
|
---|
443 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
444 | # Verify that a specified key_prefix is taken into account.
|
---|
445 | - learn_cache_key(request, response, key_prefix=key_prefix)
|
---|
446 | - self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
447 | + UpdateCacheMiddleware.learn_cache_key(request, response, key_prefix=key_prefix)
|
---|
448 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
|
---|
449 |
|
---|
450 | def test_get_cache_key_with_query(self):
|
---|
451 | request = self._get_request(self.path + '?test=1')
|
---|
452 | response = TemplateResponse(HttpResponse(), Template("This is a test"))
|
---|
453 | # Expect None if no headers have been set yet.
|
---|
454 | - self.assertEqual(get_cache_key(request), None)
|
---|
455 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), None)
|
---|
456 | # Set headers to an empty list.
|
---|
457 | - learn_cache_key(request, response)
|
---|
458 | + UpdateCacheMiddleware.learn_cache_key(request, response)
|
---|
459 | # Verify that the querystring is taken into account.
|
---|
460 | - self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.bd889c5a59603af44333ed21504db3cd.d41d8cd98f00b204e9800998ecf8427e')
|
---|
461 | + self.assertEqual(TwoPartCacheMiddlewareBase.get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.bd889c5a59603af44333ed21504db3cd.d41d8cd98f00b204e9800998ecf8427e')
|
---|
462 |
|
---|
463 | @override_settings(USE_ETAGS=False)
|
---|
464 | def test_without_etag(self):
|
---|