2011-03-28 10:11:19 +08:00
|
|
|
from functools import wraps
|
2010-03-12 21:06:13 +08:00
|
|
|
from django.utils.decorators import decorator_from_middleware_with_args, available_attrs
|
2006-05-02 09:31:56 +08:00
|
|
|
from django.utils.cache import patch_cache_control, add_never_cache_headers
|
2005-10-09 08:55:08 +08:00
|
|
|
from django.middleware.cache import CacheMiddleware
|
|
|
|
|
2010-02-09 23:02:39 +08:00
|
|
|
|
2009-09-29 05:54:54 +08:00
|
|
|
def cache_page(*args, **kwargs):
|
2010-12-04 14:49:51 +08:00
|
|
|
"""
|
|
|
|
Decorator for views that tries getting the page from the cache and
|
|
|
|
populates the cache if the page isn't in the cache yet.
|
|
|
|
|
|
|
|
The cache is keyed by the URL and some data from the headers.
|
|
|
|
Additionally there is the key prefix that is used to distinguish different
|
|
|
|
cache areas in a multi-site setup. You could use the
|
2012-09-29 02:10:22 +08:00
|
|
|
sites.get_current_site().domain, for example, as that is unique across a Django
|
2010-12-04 14:49:51 +08:00
|
|
|
project.
|
|
|
|
|
|
|
|
Additionally, all headers from the response's Vary header will be taken
|
|
|
|
into account on caching -- just like the middleware does.
|
|
|
|
"""
|
2009-09-24 07:47:53 +08:00
|
|
|
# We also add some asserts to give better error messages in case people are
|
|
|
|
# using other ways to call cache_page that no longer work.
|
2012-12-25 06:43:34 +08:00
|
|
|
if len(args) != 1 or callable(args[0]):
|
|
|
|
raise TypeError("cache_page has a single mandatory positional argument: timeout")
|
|
|
|
cache_timeout = args[0]
|
2010-12-21 23:19:19 +08:00
|
|
|
cache_alias = kwargs.pop('cache', None)
|
2009-09-29 05:54:54 +08:00
|
|
|
key_prefix = kwargs.pop('key_prefix', None)
|
2012-12-25 06:43:34 +08:00
|
|
|
if kwargs:
|
|
|
|
raise TypeError("cache_page has two optional keyword arguments: cache and key_prefix")
|
2011-06-08 19:12:01 +08:00
|
|
|
|
2012-12-25 06:43:34 +08:00
|
|
|
return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=cache_timeout, cache_alias=cache_alias, key_prefix=key_prefix)
|
2005-10-30 01:00:20 +08:00
|
|
|
|
|
|
|
|
2010-02-09 23:02:39 +08:00
|
|
|
def cache_control(**kwargs):
|
2005-10-30 01:00:20 +08:00
|
|
|
def _cache_controller(viewfunc):
|
2011-05-02 00:46:02 +08:00
|
|
|
@wraps(viewfunc, assigned=available_attrs(viewfunc))
|
2005-10-30 01:00:20 +08:00
|
|
|
def _cache_controlled(request, *args, **kw):
|
|
|
|
response = viewfunc(request, *args, **kw)
|
|
|
|
patch_cache_control(response, **kwargs)
|
|
|
|
return response
|
2011-05-02 00:46:02 +08:00
|
|
|
return _cache_controlled
|
2010-02-09 23:02:39 +08:00
|
|
|
return _cache_controller
|
2005-10-30 01:00:20 +08:00
|
|
|
|
|
|
|
|
2006-05-02 09:31:56 +08:00
|
|
|
def never_cache(view_func):
|
|
|
|
"""
|
|
|
|
Decorator that adds headers to a response so that it will
|
|
|
|
never be cached.
|
|
|
|
"""
|
2011-05-02 00:46:02 +08:00
|
|
|
@wraps(view_func, assigned=available_attrs(view_func))
|
2006-05-02 09:31:56 +08:00
|
|
|
def _wrapped_view_func(request, *args, **kwargs):
|
|
|
|
response = view_func(request, *args, **kwargs)
|
|
|
|
add_never_cache_headers(response)
|
|
|
|
return response
|
2011-05-02 00:46:02 +08:00
|
|
|
return _wrapped_view_func
|