summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorBen Lomax <lomax.on.the.run@gmail.com>2022-07-08 09:39:33 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-04-25 10:08:03 +0200
commit4dfc6ff8a81ed36dfc7c5b942ecab7217866b935 (patch)
tree0da6f1adf897c5db33438fd8c5b3c6c630659212 /django
parenta14ddc8cfccbc8da6c11e1208131abc3abd6ed5d (diff)
downloaddjango-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.py70
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)