12 """ |
12 """ |
13 |
13 |
14 try: |
14 try: |
15 from functools import wraps |
15 from functools import wraps |
16 except ImportError: |
16 except ImportError: |
17 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. |
17 from django.utils.functional import wraps # Python 2.4 fallback. |
18 |
18 |
19 from django.utils.decorators import decorator_from_middleware |
19 from django.utils.decorators import decorator_from_middleware_with_args, available_attrs |
20 from django.utils.cache import patch_cache_control, add_never_cache_headers |
20 from django.utils.cache import patch_cache_control, add_never_cache_headers |
21 from django.middleware.cache import CacheMiddleware |
21 from django.middleware.cache import CacheMiddleware |
22 |
22 |
23 cache_page = decorator_from_middleware(CacheMiddleware) |
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 |
24 |
52 |
25 def cache_control(**kwargs): |
53 def cache_control(**kwargs): |
26 |
|
27 def _cache_controller(viewfunc): |
54 def _cache_controller(viewfunc): |
28 |
|
29 def _cache_controlled(request, *args, **kw): |
55 def _cache_controlled(request, *args, **kw): |
30 response = viewfunc(request, *args, **kw) |
56 response = viewfunc(request, *args, **kw) |
31 patch_cache_control(response, **kwargs) |
57 patch_cache_control(response, **kwargs) |
32 return response |
58 return response |
|
59 return wraps(viewfunc, assigned=available_attrs(viewfunc))(_cache_controlled) |
|
60 return _cache_controller |
33 |
61 |
34 return wraps(viewfunc)(_cache_controlled) |
|
35 |
|
36 return _cache_controller |
|
37 |
62 |
38 def never_cache(view_func): |
63 def never_cache(view_func): |
39 """ |
64 """ |
40 Decorator that adds headers to a response so that it will |
65 Decorator that adds headers to a response so that it will |
41 never be cached. |
66 never be cached. |
42 """ |
67 """ |
43 def _wrapped_view_func(request, *args, **kwargs): |
68 def _wrapped_view_func(request, *args, **kwargs): |
44 response = view_func(request, *args, **kwargs) |
69 response = view_func(request, *args, **kwargs) |
45 add_never_cache_headers(response) |
70 add_never_cache_headers(response) |
46 return response |
71 return response |
47 return wraps(view_func)(_wrapped_view_func) |
72 return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view_func) |