#37065: @method_decorator can't be used on async view at class-level with
name="dispatch"
-----------------------------+--------------------------------------
Reporter: Jacob Walls | Type: Bug
Status: new | Component: Utilities
Version: 5.2 | Severity: Normal
Keywords: async | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------
`@method_decorator(..., name="dispatch")` doesn't work for async views
that don't override `dispatch()`, because `dispatch()` is sync, which is
enough to fool the logic in #35083.
{{{#!diff
diff --git a/tests/decorators/test_cache.py
b/tests/decorators/test_cache.py
index 1aca6967e0..c3b1668a7c 100644
--- a/tests/decorators/test_cache.py
+++ b/tests/decorators/test_cache.py
@@ -1,3 +1,4 @@
+from http import HTTPStatus
from inspect import iscoroutinefunction
from unittest import mock
@@ -5,6 +6,7 @@ from django.http import HttpRequest, HttpResponse
from django.test import SimpleTestCase
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control, cache_page,
never_cache
+from django.views.generic import View
class HttpRequestProxy:
@@ -217,6 +219,17 @@ class NeverCacheDecoratorTest(SimpleTestCase):
with self.assertRaisesMessage(TypeError, msg):
await MyClass().async_view(HttpRequestProxy(request))
+ async def
test_never_cache_method_decorator_http_request_async_view(self):
+ @method_decorator(never_cache, name="dispatch")
+ class MyClass(View):
+ async def get(self, request):
+ return HttpResponse()
+
+ request = HttpRequest()
+ request.method = "GET"
+ response = await MyClass().dispatch(request)
+ self.assertEqual(response.status_code, HTTPStatus.OK)
+
def test_never_cache_decorator_http_request_proxy(self):
class MyClass:
@method_decorator(never_cache)
}}}
{{{#!py
ERROR: test_never_cache_method_decorator_http_request_async_view
(decorators.test_cache.NeverCacheDecoratorTest.test_never_cache_method_decorator_http_request_async_view)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jwalls/my314/lib/python3.14/site-packages/asgiref/sync.py",
line 325, in __call__
return call_result.result()
~~~~~~~~~~~~~~~~~~^^
File
"/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/concurrent/futures/_base.py",
line 443, in result
return self.__get_result()
~~~~~~~~~~~~~~~~~^^
File
"/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/concurrent/futures/_base.py",
line 395, in __get_result
raise self._exception
File "/Users/jwalls/my314/lib/python3.14/site-packages/asgiref/sync.py",
line 365, in main_wrap
result = await awaitable
^^^^^^^^^^^^^^^
File "/Users/jwalls/django/tests/decorators/test_cache.py", line 230, in
test_never_cache_method_decorator_http_request_async_view
response = await MyClass().dispatch(request)
~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/Users/jwalls/django/django/utils/decorators.py", line 47, in
_wrapper
return bound_method(*args, **kwargs)
File "/Users/jwalls/django/django/views/decorators/cache.py", line 80,
in _view_wrapper
add_never_cache_headers(response)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/Users/jwalls/django/django/utils/cache.py", line 294, in
add_never_cache_headers
patch_response_headers(response, cache_timeout=-1)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jwalls/django/django/utils/cache.py", line 285, in
patch_response_headers
if not response.has_header("Expires"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'coroutine' object has no attribute 'has_header'
}}}
----
Moving the decorator to the method instead of the class works. We probably
will prefer a test inside the test class added in #35083 rather than
merging my sketched test.
--
Ticket URL: <https://code.djangoproject.com/ticket/37065>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/0107019dc104043e-1d3edabc-240f-49de-aad5-51be450f1ab6-000000%40eu-central-1.amazonses.com.