Response-phase cache middleware that updates the cache if the response is cacheable. Must be used as part of the two-part update/fetch cache middleware. UpdateCacheMiddleware must be the first piece of middleware in MIDDLEWARE so that it'll get called last during the response p
| 59 | |
| 60 | |
| 61 | class UpdateCacheMiddleware(MiddlewareMixin): |
| 62 | """ |
| 63 | Response-phase cache middleware that updates the cache if the response is |
| 64 | cacheable. |
| 65 | |
| 66 | Must be used as part of the two-part update/fetch cache middleware. |
| 67 | UpdateCacheMiddleware must be the first piece of middleware in MIDDLEWARE |
| 68 | so that it'll get called last during the response phase. |
| 69 | """ |
| 70 | |
| 71 | def __init__(self, get_response): |
| 72 | super().__init__(get_response) |
| 73 | self.cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS |
| 74 | self.page_timeout = None |
| 75 | self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX |
| 76 | self.cache_alias = settings.CACHE_MIDDLEWARE_ALIAS |
| 77 | |
| 78 | @property |
| 79 | def cache(self): |
| 80 | return caches[self.cache_alias] |
| 81 | |
| 82 | def _should_update_cache(self, request, response): |
| 83 | return hasattr(request, "_cache_update_cache") and request._cache_update_cache |
| 84 | |
| 85 | def process_response(self, request, response): |
| 86 | """Set the cache, if needed.""" |
| 87 | if not self._should_update_cache(request, response): |
| 88 | # We don't need to update the cache, just return. |
| 89 | return response |
| 90 | |
| 91 | if response.streaming or response.status_code not in (200, 304): |
| 92 | return response |
| 93 | |
| 94 | # Don't cache responses that set a user-specific (and maybe security |
| 95 | # sensitive) cookie in response to a cookie-less request. |
| 96 | if ( |
| 97 | not request.COOKIES |
| 98 | and response.cookies |
| 99 | and has_vary_header(response, "Cookie") |
| 100 | ): |
| 101 | return response |
| 102 | |
| 103 | # Don't cache responses when the Cache-Control header is set to |
| 104 | # private, no-cache, or no-store. |
| 105 | cache_control = response.get("Cache-Control", ()) |
| 106 | if any( |
| 107 | directive in cache_control |
| 108 | for directive in ( |
| 109 | "private", |
| 110 | "no-cache", |
| 111 | "no-store", |
| 112 | ) |
| 113 | ): |
| 114 | return response |
| 115 | |
| 116 | # Don't cache responses when the Vary header contains '*'. |
| 117 | if has_vary_header(response, "*"): |
| 118 | return response |
no outgoing calls
searching dependent graphs…