1
0
mirror of https://github.com/django/django.git synced 2025-10-24 14:16:09 +00:00

Fixed #33611 -- Allowed View subclasses to define async method handlers.

This commit is contained in:
Carlton Gibson
2022-04-07 07:05:59 +02:00
committed by GitHub
parent 2ee4caf56b
commit 9ffd4eae2c
6 changed files with 168 additions and 4 deletions

View File

@@ -77,6 +77,17 @@ MRO is an acronym for Method Resolution Order.
<how-django-processes-a-request>` 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``
================

View File

@@ -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

View File

@@ -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::

View File

@@ -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`.