Django middleware learning - Cache
The middleware cache code is in the django/middleware/cache.py file
When using cache middleware, you must configure the following
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
...
'django.middleware.cache.FetchFromCacheMiddleware'
]
UpdateCacheMiddleware
caches the response FetchFromCacheMiddleware takes out the cached response
UpdateCacheMiddleware function logic
To determine whether request._cache_update_cache is True, the value of _cache_update_cache is set in FetchFromCacheMiddleware
if not self._should_update_cache(request, response):
# We don't need to update the cache, just return.
return response
def _should_update_cache(self, request, response):
return hasattr(request, '_cache_update_cache') and request._cache_update_cache
The status of the response is not 200 and 304, the request and response have cookies and are not cached, and the Cache-Control in the response is not private
and not cached
if response.streaming or response.status_code not in (200, 304):
return response
# Don't cache responses that set a user-specific (and maybe security
# sensitive) cookie in response to a cookie-less request.
if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'):
return response
# Don't cache a response with 'Cache-Control: private'
if 'private' in response.get('Cache-Control', ()):
return response
The next step is to set the response header ETag Expires max_age
patch_response_headers(response, timeout)
Finally, set the cache
if timeout and response.status_code == 200:
cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache)
if hasattr(response, 'render') and callable(response.render):
response.add_post_render_callback(
lambda r: self.cache.set(cache_key, r, timeout)
)
else:
self.cache.set(cache_key, response, timeout)
FetchFromCacheMiddleware
Use request to generate the corresponding cache_key
If cache_key is None, set _cache_update_cache = True, this attribute will be used in UpdateCacheMiddleware to fetch cache
according to cache_key
# try and get the cached GET response
cache_key = get_cache_key(request, self.key_prefix, 'GET', cache=self.cache)
if cache_key is None:
request._cache_update_cache = True
return None # No cache information available, need to rebuild.
response = self.cache.get(cache_key)