|
| 1 | +from django.middleware.cache import UpdateCacheMiddleware |
| 2 | + |
| 3 | +from django.utils.cache import learn_cache_key, get_max_age |
| 4 | + |
| 5 | + |
| 6 | +class UpdateCacheMiddlewareNoHeaders(UpdateCacheMiddleware): |
| 7 | + """ |
| 8 | + Just like UpdateCacheMiddleware but we don't set cache headers in the |
| 9 | + HTTP response. |
| 10 | + """ |
| 11 | + def process_response(self, request, response): |
| 12 | + """Sets the cache, if needed.""" |
| 13 | + if not self._should_update_cache(request, response): |
| 14 | + # We don't need to update the cache, just return. |
| 15 | + return response |
| 16 | + if not response.status_code == 200: |
| 17 | + return response |
| 18 | + # Try to get the timeout from the "max-age" section of the "Cache- |
| 19 | + # Control" header before reverting to using the default cache_timeout |
| 20 | + # length. |
| 21 | + timeout = get_max_age(response) |
| 22 | + if timeout == None: |
| 23 | + timeout = self.cache_timeout |
| 24 | + elif timeout == 0: |
| 25 | + # max-age was set to 0, don't bother caching. |
| 26 | + return response |
| 27 | + #patch_response_headers(response, timeout) |
| 28 | + if timeout: |
| 29 | + cache_key = learn_cache_key( |
| 30 | + request, response, timeout, self.key_prefix, cache=self.cache) |
| 31 | + if hasattr(response, 'render') and callable(response.render): |
| 32 | + response.add_post_render_callback( |
| 33 | + lambda r: self.cache.set(cache_key, r, timeout) |
| 34 | + ) |
| 35 | + else: |
| 36 | + self.cache.set(cache_key, response, timeout) |
| 37 | + return response |
| 38 | + |
| 39 | + |
| 40 | +class UpdateCacheMiddlewareNoEdit(UpdateCacheMiddleware): |
| 41 | + """ |
| 42 | + Just like UpdateCacheMiddleware but don't cache anything from anyone |
| 43 | + who has the 'has_POSTed' session flag. We use this because the default |
| 44 | + CACHE_MIDDLEWARE_ANONYMOUS_ONLY will still cache non-logged in users' |
| 45 | + edits, etc. So we sort of say that 'anonymous,' in our case, is really |
| 46 | + anyone who's never made an edit. |
| 47 | + """ |
| 48 | + def _should_update_cache(self, request, response): |
| 49 | + if (not hasattr(request, '_cache_update_cache') or |
| 50 | + not request._cache_update_cache): |
| 51 | + return False |
| 52 | + # If the session has not been accessed otherwise, we don't want to |
| 53 | + # cause it to be accessed here. If it hasn't been accessed, then the |
| 54 | + # user's logged-in status has not affected the response anyway. |
| 55 | + if self.cache_anonymous_only and self._session_accessed(request): |
| 56 | + assert hasattr(request, 'user'), "The Django cache middleware with CACHE_MIDDLEWARE_ANONYMOUS_ONLY=True requires authentication middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.auth.middleware.AuthenticationMiddleware' before the CacheMiddleware." |
| 57 | + if request.user.is_authenticated() or request.session.get('has_POSTed'): |
| 58 | + # Don't cache user-variable requests from authenticated users. |
| 59 | + return False |
| 60 | + return True |
| 61 | + |
| 62 | + |
| 63 | +class UpdateCacheMiddleware(UpdateCacheMiddlewareNoEdit, UpdateCacheMiddlewareNoHeaders): |
| 64 | + pass |
| 65 | + |
| 66 | + |
| 67 | +class TrackPOSTMiddleware(object): |
| 68 | + def process_request(self, request): |
| 69 | + if request.method == 'POST' and 'has_POSTed' not in request.session: |
| 70 | + request.session['has_POSTed'] = True |
0 commit comments