Django 3.1 async view is done (=> async phase 2 is done !) ¶
See also
-
https://groups.google.com/forum/#!msg/django-developers/5CVsR9FSqmg/UiswdhLECAAJ
-
https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django
-
https://github.com/django/django/commit/fc0fa72ff4cdbf5861a366e31cb8bbacd44da22d
-
https://docs.djangoproject.com/en/dev/releases/3.1/#asynchronous-views-and-middleware-support
-
https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django?slide=42
-
AnyIO, a Python library providing structured concurrency primitives on top of asyncio
-
sniffio Sniff out which async library your code is running under
Contents
History ¶
Phase 1 : Django 3.0 ¶
Phase 2 : Django 3.1 ¶

https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django?slide=61 https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django?slide=1 ¶
Django 3.1 announce ¶
See also
To get started with async views , you need to declare a view using async def :
Example 1 ¶
# https://docs.python.org/3/library/asyncio.html
# https://docs.python.org/3/library/asyncio-api-index.html
import asyncio
async def my_view(request):
await asyncio.sleep(0.5)
return HttpResponse('Hello, async world!')
Example 2 ¶
models.py ¶
1 # https://docs.python.org/3/library/asyncio-task.html
2 import asyncio
3 # https://docs.djangoproject.com/en/3.1/topics/async/#async-to-sync
4 from asgiref.sync import sync_to_async
5 def sync_update_conges():
6 print("Begin sync_update_conges()")
7 PROJETS_CONGES = Projet.objects.filter(designation__icontains="abs")
8 PROJETS_CONGES_ID = [p.id for p in PROJETS_CONGES]
9
10
11 loop = asyncio.get_event_loop()
12 async_function = sync_to_async(sync_update_conges)
13 loop.create_task(async_function())
Example 3 async Django ¶
urls.py ¶
1 path("asyncview/test1", views_asgi.async_view_test_1, name="asgi_async_view_test1"),
2 path("syncview/test1", views_asgi.sync_view_test_1, name="asgi_sync_view_test1"),
3 path(
4 "asyncview/smoke_some_meats",
5 views_asgi.smoke_some_meats,
6 name="asgi_async_smoke_some_meats",
7 ),
8 path(
9 "asyncview/async_hello", views_asgi.async_hello, name="asgi_async_async_hello"
10 ),
views_asgi.py ¶
1 # https://docs.python.org/3/library/asyncio-task.html
2 import asyncio
3 # https://docs.djangoproject.com/en/3.1/topics/async/#async-to-sync
4 from asgiref.sync import sync_to_async
5
6 def orm_get_fiches_temps_en_calcul() -> None:
7 """Incrément du temps passé pour les FICHE_EN_CALCUL."""
8 now = datetime.now()
9 logger.info(
10 f"Begin task_update_fiches_temps_en_calcul() {now.hour:02}H{now.minute:02}mn{now.second:02}s"
11 )
12 liste_fiches_en_calcul = None
13 try:
14 liste_fiches_en_calcul = FicheTemps.objects.filter(
15 etat=FICHE_STATUS["FICHE_EN_CALCUL"]
16 )
17 if liste_fiches_en_calcul.count() == 0:
18 now = datetime.now()
19 logger.info(
20 f"pas de fiches en calcul {now.hour:02}H{now.minute:02}mn{now.second:02}s"
21 )
22 else:
23 # parcours des fiches de temps en calcul
24 for fiches_temps in liste_fiches_en_calcul:
25 try:
26 fiches_temps.temps_impute = fiches_temps.temps_impute + timedelta(
27 seconds=INCREMENT_TIME_SECONDS
28 )
29 logger.info(f"Temps impute:{fiches_temps.temps_impute}")
30 fiches_temps.save()
31 except:
32 logger.error("task_update_fiches_temps_en_calcul()")
33
34 except Exception as error:
35 logger.error(f"Pb in task_update_fiches_temps_en_calcul = {error=}")
36
37 return liste_fiches_en_calcul
38
39
40 async def _async_hello():
41 while True:
42 loop = asyncio.get_event_loop()
43 async_function = sync_to_async(orm_get_fiches_temps_en_calcul)
44 loop.create_task(async_function())
45 await asyncio.sleep(5)
46
47
48 async def async_hello(request: HttpRequest) -> HttpResponse:
49 """Tâche périodique asynchrone.
50
51 http://localhost:8004/fiches_temps/asyncview/async_hello
52 """
53 loop = asyncio.get_event_loop()
54 loop.create_task(_async_hello())
55 return HttpResponse(f"Non blocking hello")
All asynchronous features are supported whether you are running under WSGI or ASGI mode .
However, there will be performance penalties using async code in WSGI mode .
You can read more about the specifics in Asynchronous support documentation .
You are free to mix async and sync views, middleware, and tests as much as you want. Django will ensure that you always end up with the right execution context.
We expect most projects will keep the majority of their views synchronous, and only have a select few running in async mode but it is entirely your choice .
Django’s ORM, cache layer, and other pieces of code that do long-running network calls do not yet support async access .
We expect to add support for them in upcoming releases .
Async views are ideal, however, if you are doing a lot of API or HTTP calls inside your view, you can now natively do all those HTTP calls in parallel to considerably speed up your view’s execution.
Asynchronous support should be entirely backwards-compatible and we have tried to ensure that it has no speed regressions for your existing, synchronous code.
It should have no noticeable effect on any existing Django projects.
Mariusz Felisiak ¶
Many thanks to @andrewgodwin for adding support for async views, middleware, and tests to #Django #async

https://twitter.com/MariuszFelisiak/status/1240357596315467778?s=20 ¶
Andrew Godwin ¶
See also
-
https://github.com/django/django/commit/fc0fa72ff4cdbf5861a366e31cb8bbacd44da22d
-
https://arunrocks.com/a-guide-to-asgi-in-django-30-and-its-performance/
-
https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django?slide=1
-
https://speakerdeck.com/andrewgodwin/just-add-await-retrofitting-async-into-django?slide=42
It is done - Django 3.1 will have async views ! Thanks to everyone who’s helped out with this.

https://twitter.com/andrewgodwin/status/1240357729174052866?s=20 ¶
The fc0fa72ff4cdb git commit ¶
Simon Willison ¶
See also

https://twitter.com/simonw/status/1287146436837044224?s=20 ¶
Node is a tempting option for anything involving comet, file uploads or
even just mashing together potentially slow loading web APIs.
10.5 years later, I'm excited about async views in Django 3.1 for exactly
the same reasons (except we don't call live updates "comet" any more)
Tutorials ¶
- Asynchronous topics by Django documentation
- Async Views in Django 3.1 by Jace Medlin , August 17th, 2020
- Django 3.1 Async by Jochen Wersdörfer (https://twitter.com/ephes) Aug. 4, 2020
-
A Guide to ASGI in Django 3.0 and its Performance by
Arun Ravindran
, Mar 10, 2020
- Introduction
- Before ASGI there was WSGI
- Road ‘Blocks’ to Scale
- Two Worlds of Python
- Django Evolves
- Django talks ASGI
- How to use ASGI ?
- Running Existing Django Projects under ASGI
- Gotchas
- ASGI vs WSGI Performance
- Frequent Questions
- Will upgrading to Django 3.0 break my project ?
- Q. Can I continue to use WSGI ?
- When can I write async code in Django ?
- Wrapping Up
- Django Async: What’s new and what’s next ? By Sanket on August 14, 2020