|
0
|
1 |
""" |
|
|
2 |
Decorator for views that tries getting the page from the cache and |
|
|
3 |
populates the cache if the page isn't in the cache yet. |
|
|
4 |
|
|
|
5 |
The cache is keyed by the URL and some data from the headers. Additionally |
|
|
6 |
there is the key prefix that is used to distinguish different cache areas |
|
|
7 |
in a multi-site setup. You could use the sites.get_current().domain, for |
|
|
8 |
example, as that is unique across a Django project. |
|
|
9 |
|
|
|
10 |
Additionally, all headers from the response's Vary header will be taken into |
|
|
11 |
account on caching -- just like the middleware does. |
|
|
12 |
""" |
|
|
13 |
|
|
|
14 |
try: |
|
|
15 |
from functools import wraps |
|
|
16 |
except ImportError: |
|
29
|
17 |
from django.utils.functional import wraps # Python 2.4 fallback. |
|
0
|
18 |
|
|
29
|
19 |
from django.utils.decorators import decorator_from_middleware_with_args, available_attrs |
|
0
|
20 |
from django.utils.cache import patch_cache_control, add_never_cache_headers |
|
|
21 |
from django.middleware.cache import CacheMiddleware |
|
|
22 |
|
|
29
|
23 |
|
|
|
24 |
def cache_page(*args, **kwargs): |
|
|
25 |
# We need backwards compatibility with code which spells it this way: |
|
|
26 |
# def my_view(): pass |
|
|
27 |
# my_view = cache_page(my_view, 123) |
|
|
28 |
# and this way: |
|
|
29 |
# my_view = cache_page(123)(my_view) |
|
|
30 |
# and this: |
|
|
31 |
# my_view = cache_page(my_view, 123, key_prefix="foo") |
|
|
32 |
# and this: |
|
|
33 |
# my_view = cache_page(123, key_prefix="foo")(my_view) |
|
|
34 |
# and possibly this way (?): |
|
|
35 |
# my_view = cache_page(123, my_view) |
|
|
36 |
|
|
|
37 |
# We also add some asserts to give better error messages in case people are |
|
|
38 |
# using other ways to call cache_page that no longer work. |
|
|
39 |
key_prefix = kwargs.pop('key_prefix', None) |
|
|
40 |
assert not kwargs, "The only keyword argument accepted is key_prefix" |
|
|
41 |
if len(args) > 1: |
|
|
42 |
assert len(args) == 2, "cache_page accepts at most 2 arguments" |
|
|
43 |
if callable(args[0]): |
|
|
44 |
return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[1], key_prefix=key_prefix)(args[0]) |
|
|
45 |
elif callable(args[1]): |
|
|
46 |
return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[0], key_prefix=key_prefix)(args[1]) |
|
|
47 |
else: |
|
|
48 |
assert False, "cache_page must be passed either a single argument (timeout) or a view function and a timeout" |
|
|
49 |
else: |
|
|
50 |
return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[0], key_prefix=key_prefix) |
|
|
51 |
|
|
0
|
52 |
|
|
|
53 |
def cache_control(**kwargs): |
|
|
54 |
def _cache_controller(viewfunc): |
|
|
55 |
def _cache_controlled(request, *args, **kw): |
|
|
56 |
response = viewfunc(request, *args, **kw) |
|
|
57 |
patch_cache_control(response, **kwargs) |
|
|
58 |
return response |
|
29
|
59 |
return wraps(viewfunc, assigned=available_attrs(viewfunc))(_cache_controlled) |
|
|
60 |
return _cache_controller |
|
0
|
61 |
|
|
|
62 |
|
|
|
63 |
def never_cache(view_func): |
|
|
64 |
""" |
|
|
65 |
Decorator that adds headers to a response so that it will |
|
|
66 |
never be cached. |
|
|
67 |
""" |
|
|
68 |
def _wrapped_view_func(request, *args, **kwargs): |
|
|
69 |
response = view_func(request, *args, **kwargs) |
|
|
70 |
add_never_cache_headers(response) |
|
|
71 |
return response |
|
29
|
72 |
return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view_func) |