diff -r 8d941af65caf -r 77b6da96e6f1 web/lib/django/views/decorators/cache.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/django/views/decorators/cache.py Wed Jun 02 18:57:35 2010 +0200 @@ -0,0 +1,72 @@ +""" +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 sites.get_current().domain, for +example, as that is unique across a Django project. + +Additionally, all headers from the response's Vary header will be taken into +account on caching -- just like the middleware does. +""" + +try: + from functools import wraps +except ImportError: + from django.utils.functional import wraps # Python 2.4 fallback. + +from django.utils.decorators import decorator_from_middleware_with_args, available_attrs +from django.utils.cache import patch_cache_control, add_never_cache_headers +from django.middleware.cache import CacheMiddleware + + +def cache_page(*args, **kwargs): + # We need backwards compatibility with code which spells it this way: + # def my_view(): pass + # my_view = cache_page(my_view, 123) + # and this way: + # my_view = cache_page(123)(my_view) + # and this: + # my_view = cache_page(my_view, 123, key_prefix="foo") + # and this: + # my_view = cache_page(123, key_prefix="foo")(my_view) + # and possibly this way (?): + # my_view = cache_page(123, my_view) + + # 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. + key_prefix = kwargs.pop('key_prefix', None) + assert not kwargs, "The only keyword argument accepted is key_prefix" + if len(args) > 1: + assert len(args) == 2, "cache_page accepts at most 2 arguments" + if callable(args[0]): + return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[1], key_prefix=key_prefix)(args[0]) + elif callable(args[1]): + return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[0], key_prefix=key_prefix)(args[1]) + else: + assert False, "cache_page must be passed either a single argument (timeout) or a view function and a timeout" + else: + return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[0], key_prefix=key_prefix) + + +def cache_control(**kwargs): + def _cache_controller(viewfunc): + def _cache_controlled(request, *args, **kw): + response = viewfunc(request, *args, **kw) + patch_cache_control(response, **kwargs) + return response + return wraps(viewfunc, assigned=available_attrs(viewfunc))(_cache_controlled) + return _cache_controller + + +def never_cache(view_func): + """ + Decorator that adds headers to a response so that it will + never be cached. + """ + def _wrapped_view_func(request, *args, **kwargs): + response = view_func(request, *args, **kwargs) + add_never_cache_headers(response) + return response + return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view_func)