From 9ffd4eae2ce7a7100c98f681e2b6ab818df384a4 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Thu, 7 Apr 2022 07:05:59 +0200 Subject: Fixed #33611 -- Allowed View subclasses to define async method handlers. --- docs/ref/class-based-views/base.txt | 19 +++++++++++++++++++ docs/releases/4.1.txt | 17 +++++++++++++++++ docs/topics/async.txt | 5 +++-- docs/topics/class-based-views/index.txt | 30 ++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt index 5c2eb712c1..f60950d1fa 100644 --- a/docs/ref/class-based-views/base.txt +++ b/docs/ref/class-based-views/base.txt @@ -77,6 +77,17 @@ MRO is an acronym for Method Resolution Order. ` to the ``args`` and ``kwargs`` attributes, respectively. Then :meth:`dispatch` is called. + If a ``View`` subclass defines asynchronous (``async def``) method + handlers, ``as_view()`` will mark the returned callable as a coroutine + function. An ``ImproperlyConfigured`` exception will be raised if both + asynchronous (``async def``) and synchronous (``def``) handlers are + defined on a single view-class. + + .. versionchanged:: 4.1 + + Compatibility with asynchronous (``async def``) method handlers was + added. + .. method:: setup(request, *args, **kwargs) Performs key view initialization prior to :meth:`dispatch`. @@ -111,6 +122,14 @@ MRO is an acronym for Method Resolution Order. response with the ``Allow`` header containing a list of the view's allowed HTTP method names. + If the other HTTP methods handlers on the class are asynchronous + (``async def``) then the response will be wrapped in a coroutine + function for use with ``await``. + + .. versionchanged:: 4.1 + + Compatibility with classes defining asynchronous (``async def``) + method handlers was added. ``TemplateView`` ================ diff --git a/docs/releases/4.1.txt b/docs/releases/4.1.txt index d83da638fc..2ec0d42cdd 100644 --- a/docs/releases/4.1.txt +++ b/docs/releases/4.1.txt @@ -26,6 +26,23 @@ officially support the latest release of each series. What's new in Django 4.1 ======================== +Asynchronous handlers for class-based views +------------------------------------------- + +View subclasses may now define async HTTP method handlers:: + + import asyncio + from django.http import HttpResponse + from django.views import View + + class AsyncView(View): + async def get(self, request, *args, **kwargs): + # Perform view logic using await. + await asyncio.sleep(1) + return HttpResponse("Hello async world!") + +See :ref:`async-class-based-views` for more details. + .. _csrf-cookie-masked-usage: ``CSRF_COOKIE_MASKED`` setting diff --git a/docs/topics/async.txt b/docs/topics/async.txt index 90a31b994b..ab2ccd3c98 100644 --- a/docs/topics/async.txt +++ b/docs/topics/async.txt @@ -22,8 +22,9 @@ Async views Any view can be declared async by making the callable part of it return a coroutine - commonly, this is done using ``async def``. For a function-based view, this means declaring the whole view using ``async def``. For a -class-based view, this means making its ``__call__()`` method an ``async def`` -(not its ``__init__()`` or ``as_view()``). +class-based view, this means declaring the HTTP method handlers, such as +``get()`` and ``post()`` as ``async def`` (not its ``__init__()``, or +``as_view()``). .. note:: diff --git a/docs/topics/class-based-views/index.txt b/docs/topics/class-based-views/index.txt index 01f9c35460..1a6368cc08 100644 --- a/docs/topics/class-based-views/index.txt +++ b/docs/topics/class-based-views/index.txt @@ -128,3 +128,33 @@ the response (using the ``book_list.html`` template). But if the client issues a ``HEAD`` request, the response has an empty body and the ``Last-Modified`` header indicates when the most recent book was published. Based on this information, the client may or may not download the full object list. + +.. _async-class-based-views: + +Asynchronous class-based views +============================== + +.. versionadded:: 4.1 + +As well as the synchronous (``def``) method handlers already shown, ``View`` +subclasses may define asynchronous (``async def``) method handlers to leverage +asynchronous code using ``await``:: + + import asyncio + from django.http import HttpResponse + from django.views import View + + class AsyncView(View): + async def get(self, request, *args, **kwargs): + # Perform io-blocking view logic using await, sleep for example. + await asyncio.sleep(1) + return HttpResponse("Hello async world!") + +Within a single view-class, all user-defined method handlers must be either +synchronous, using ``def``, or all asynchronous, using ``async def``. An +``ImproperlyConfigured`` exception will be raised in ``as_view()`` if ``def`` +and ``async def`` declarations are mixed. + +Django will automatically detect asynchronous views and run them in an +asynchronous context. You can read more about Django's asynchronous support, +and how to best use async views, in :doc:`/topics/async`. -- cgit v1.3