diff options
author | Ben Lomax <lomax.on.the.run@gmail.com> | 2022-07-08 09:39:33 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-04-25 10:08:03 +0200 |
commit | 4dfc6ff8a81ed36dfc7c5b942ecab7217866b935 (patch) | |
tree | 0da6f1adf897c5db33438fd8c5b3c6c630659212 /django | |
parent | a14ddc8cfccbc8da6c11e1208131abc3abd6ed5d (diff) | |
download | django-4dfc6ff8a81ed36dfc7c5b942ecab7217866b935.tar.gz |
Refs #31949 -- Made @never_cache and @cache_control() decorators to work with async functions.
Thanks Carlton Gibson and Mariusz Felisiak for reviews.
Diffstat (limited to 'django')
-rw-r--r-- | django/views/decorators/cache.py | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index 6004b2f138..aa1679baff 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -1,5 +1,7 @@ from functools import wraps +from asgiref.sync import iscoroutinefunction + from django.middleware.cache import CacheMiddleware from django.utils.cache import add_never_cache_headers, patch_cache_control from django.utils.decorators import decorator_from_middleware_with_args @@ -26,22 +28,34 @@ def cache_page(timeout, *, cache=None, key_prefix=None): ) +def _check_request(request, decorator_name): + # Ensure argument looks like a request. + if not hasattr(request, "META"): + raise TypeError( + f"{decorator_name} didn't receive an HttpRequest. If you are " + "decorating a classmethod, be sure to use @method_decorator." + ) + + def cache_control(**kwargs): def _cache_controller(viewfunc): - @wraps(viewfunc) - def _cache_controlled(request, *args, **kw): - # Ensure argument looks like a request. - if not hasattr(request, "META"): - raise TypeError( - "cache_control didn't receive an HttpRequest. If you are " - "decorating a classmethod, be sure to use " - "@method_decorator." - ) - response = viewfunc(request, *args, **kw) - patch_cache_control(response, **kwargs) - return response + if iscoroutinefunction(viewfunc): + + async def _view_wrapper(request, *args, **kw): + _check_request(request, "cache_control") + response = await viewfunc(request, *args, **kw) + patch_cache_control(response, **kwargs) + return response + + else: + + def _view_wrapper(request, *args, **kw): + _check_request(request, "cache_control") + response = viewfunc(request, *args, **kw) + patch_cache_control(response, **kwargs) + return response - return _cache_controlled + return wraps(viewfunc)(_view_wrapper) return _cache_controller @@ -51,16 +65,20 @@ def never_cache(view_func): Decorator that adds headers to a response so that it will never be cached. """ - @wraps(view_func) - def _wrapper_view_func(request, *args, **kwargs): - # Ensure argument looks like a request. - if not hasattr(request, "META"): - raise TypeError( - "never_cache didn't receive an HttpRequest. If you are " - "decorating a classmethod, be sure to use @method_decorator." - ) - response = view_func(request, *args, **kwargs) - add_never_cache_headers(response) - return response - - return _wrapper_view_func + if iscoroutinefunction(view_func): + + async def _view_wrapper(request, *args, **kwargs): + _check_request(request, "never_cache") + response = await view_func(request, *args, **kwargs) + add_never_cache_headers(response) + return response + + else: + + def _view_wrapper(request, *args, **kwargs): + _check_request(request, "never_cache") + response = view_func(request, *args, **kwargs) + add_never_cache_headers(response) + return response + + return wraps(view_func)(_view_wrapper) |