2005-07-19 03:07:37 +08:00
from django . conf import settings
from django . core . cache import cache
2007-11-30 00:57:18 +08:00
from django . utils . cache import get_cache_key , learn_cache_key , patch_response_headers , get_max_age
2005-07-19 03:07:37 +08:00
2006-06-08 13:00:13 +08:00
class CacheMiddleware ( object ) :
2005-07-19 03:07:37 +08:00
"""
Cache middleware . If this is enabled , each Django - powered page will be
2007-11-30 00:57:18 +08:00
cached ( based on URLs ) .
2005-07-19 03:07:37 +08:00
2005-10-09 08:55:08 +08:00
Only parameter - less GET or HEAD - requests with status code 200 are cached .
2005-07-19 03:07:37 +08:00
2007-11-30 00:57:18 +08:00
The number of seconds each page is stored for is set by the
" max-age " section of the response ' s " Cache-Control " header, falling back to
the CACHE_MIDDLEWARE_SECONDS setting if the section was not found .
2006-07-20 23:37:12 +08:00
If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True , only anonymous requests
2007-03-26 02:05:01 +08:00
( i . e . , those not made by a logged - in user ) will be cached . This is a
2006-07-20 23:37:12 +08:00
simple and effective way of avoiding the caching of the Django admin ( and
any other user - specific content ) .
2005-10-09 08:55:08 +08:00
This middleware expects that a HEAD request is answered with a response
exactly like the corresponding GET request .
2005-07-19 03:07:37 +08:00
2005-10-09 08:55:08 +08:00
When a hit occurs , a shallow copy of the original response object is
returned from process_request .
2005-07-19 03:07:37 +08:00
2005-10-09 08:55:08 +08:00
Pages will be cached based on the contents of the request headers
listed in the response ' s " Vary " header. This means that pages shouldn ' t
change their " Vary " header .
This middleware also sets ETag , Last - Modified , Expires and Cache - Control
headers on the response object .
2005-07-19 03:07:37 +08:00
"""
2006-07-20 23:37:12 +08:00
def __init__ ( self , cache_timeout = None , key_prefix = None , cache_anonymous_only = None ) :
2005-10-09 08:55:08 +08:00
self . cache_timeout = cache_timeout
if cache_timeout is None :
self . cache_timeout = settings . CACHE_MIDDLEWARE_SECONDS
self . key_prefix = key_prefix
if key_prefix is None :
self . key_prefix = settings . CACHE_MIDDLEWARE_KEY_PREFIX
2006-07-20 23:37:51 +08:00
if cache_anonymous_only is None :
2006-07-21 22:41:38 +08:00
self . cache_anonymous_only = getattr ( settings , ' CACHE_MIDDLEWARE_ANONYMOUS_ONLY ' , False )
2006-07-20 23:37:12 +08:00
else :
self . cache_anonymous_only = cache_anonymous_only
2005-10-09 08:55:08 +08:00
2005-07-19 03:07:37 +08:00
def process_request ( self , request ) :
2005-10-09 08:55:08 +08:00
" Checks whether the page is already cached and returns the cached version if available. "
2006-08-18 11:31:13 +08:00
if self . cache_anonymous_only :
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. "
2006-06-20 12:34:13 +08:00
if not request . method in ( ' GET ' , ' HEAD ' ) or request . GET :
2005-10-09 08:55:08 +08:00
request . _cache_update_cache = False
2005-07-19 03:07:37 +08:00
return None # Don't bother checking the cache.
2006-07-20 23:37:12 +08:00
if self . cache_anonymous_only and request . user . is_authenticated ( ) :
request . _cache_update_cache = False
return None # Don't cache requests from authenticated users.
2005-10-09 08:55:08 +08:00
cache_key = get_cache_key ( request , self . key_prefix )
if cache_key is None :
request . _cache_update_cache = True
return None # No cache information available, need to rebuild.
2005-07-19 03:07:37 +08:00
response = cache . get ( cache_key , None )
if response is None :
2005-10-09 08:55:08 +08:00
request . _cache_update_cache = True
return None # No cache information available, need to rebuild.
request . _cache_update_cache = False
2005-10-10 21:56:39 +08:00
return response
2005-07-19 03:07:37 +08:00
def process_response ( self , request , response ) :
2005-10-09 08:55:08 +08:00
" Sets the cache, if needed. "
2005-10-19 21:44:55 +08:00
if not hasattr ( request , ' _cache_update_cache ' ) or not request . _cache_update_cache :
2005-10-09 08:55:08 +08:00
# We don't need to update the cache, just return.
return response
2006-06-20 12:34:13 +08:00
if request . method != ' GET ' :
2005-10-09 08:55:08 +08:00
# This is a stronger requirement than above. It is needed
# because of interactions between this middleware and the
# HTTPMiddleware, which throws the body of a HEAD-request
# away before this middleware gets a chance to cache it.
return response
if not response . status_code == 200 :
return response
2007-11-30 00:57:18 +08:00
# Try to get the timeout from the "max-age" section of the "Cache-
# Control" header before reverting to using the default cache_timeout
# length.
timeout = get_max_age ( response )
if timeout == None :
timeout = self . cache_timeout
elif timeout == 0 :
# max-age was set to 0, don't bother caching.
return response
patch_response_headers ( response , timeout )
cache_key = learn_cache_key ( request , response , timeout , self . key_prefix )
cache . set ( cache_key , response , timeout )
2005-07-19 03:07:37 +08:00
return response