Skip to content

Commit 49624ea

Browse files
committed
Add asynchronous examples (#1819)
1 parent c911d73 commit 49624ea

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

example/README.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,13 @@ environment variable::
4646

4747
$ DB_BACKEND=postgresql python example/manage.py migrate
4848
$ DB_BACKEND=postgresql python example/manage.py runserver
49+
50+
Using an asynchronous (ASGI) server:
51+
52+
Install [Daphne](https://pypi.org/project/daphne/) first:
53+
54+
$ python -m pip install daphne
55+
56+
Then run the Django development server:
57+
58+
$ ASYNC_SERVER=true python example/manage.py runserver

example/asgi.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""ASGI config for example project."""
2+
3+
import os
4+
5+
from django.core.asgi import get_asgi_application
6+
7+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
8+
9+
application = get_asgi_application()

example/settings.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# Application definition
1717

1818
INSTALLED_APPS = [
19+
*(["daphne"] if os.getenv("ASYNC_SERVER", False) else []),
1920
"django.contrib.admin",
2021
"django.contrib.auth",
2122
"django.contrib.contenttypes",
@@ -60,6 +61,7 @@
6061
USE_TZ = True
6162

6263
WSGI_APPLICATION = "example.wsgi.application"
64+
ASGI_APPLICATION = "example.asgi.application"
6365

6466
DEBUG_TOOLBAR_CONFIG = {"ROOT_TAG_EXTRA_ATTRS": "data-turbo-permanent hx-preserve"}
6567

@@ -97,3 +99,26 @@
9799
}
98100

99101
STATICFILES_DIRS = [os.path.join(BASE_DIR, "example", "static")]
102+
103+
LOGGING = {
104+
"version": 1,
105+
"disable_existing_loggers": False,
106+
"handlers": {
107+
"console": {
108+
"class": "logging.StreamHandler",
109+
},
110+
},
111+
"root": {
112+
"handlers": ["console"],
113+
"level": "WARNING",
114+
},
115+
"loggers": {
116+
# Log when an asynchronous handler is adapted for middleware.
117+
# See warning here: https://docs.djangoproject.com/en/4.2/topics/async/#async-views
118+
"django.request": {
119+
"handlers": ["console"],
120+
"level": os.getenv("DJANGO_REQUEST_LOG_LEVEL", "INFO"),
121+
"propagate": False,
122+
},
123+
},
124+
}

example/templates/async_db.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
5+
<title>Async DB</title>
6+
</head>
7+
<body>
8+
<h1>Async DB</h1>
9+
<p>
10+
<span>Value </span>
11+
<span>{{ user_count }}</span>
12+
</p>
13+
</body>
14+
</html>

example/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from django.urls import include, path
33
from django.views.generic import TemplateView
44

5-
from example.views import increment
5+
from example.views import async_db, async_db_concurrent, async_home, increment
66

77
urlpatterns = [
88
path("", TemplateView.as_view(template_name="index.html"), name="home"),
9+
path("async/", async_home, name="async_home"),
10+
path("async/db/", async_db, name="async_db"),
11+
path("async/db-concurrent/", async_db_concurrent, name="async_db_concurrent"),
912
path("jquery/", TemplateView.as_view(template_name="jquery/index.html")),
1013
path("mootools/", TemplateView.as_view(template_name="mootools/index.html")),
1114
path("prototype/", TemplateView.as_view(template_name="prototype/index.html")),

example/views.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import asyncio
2+
3+
from asgiref.sync import sync_to_async
4+
from django.contrib.auth.models import User
15
from django.http import JsonResponse
6+
from django.shortcuts import render
27

38

49
def increment(request):
@@ -8,3 +13,23 @@ def increment(request):
813
value = 1
914
request.session["value"] = value
1015
return JsonResponse({"value": value})
16+
17+
18+
async def async_home(request):
19+
return await sync_to_async(render)(request, "index.html")
20+
21+
22+
async def async_db(request):
23+
user_count = await User.objects.acount()
24+
25+
return await sync_to_async(render)(request, "async_db.html", {"user_count": user_count})
26+
27+
28+
async def async_db_concurrent(request):
29+
# Do database queries concurrently
30+
(user_count, _) = await asyncio.gather(
31+
User.objects.acount(),
32+
User.objects.filter(username="test").acount()
33+
)
34+
35+
return await sync_to_async(render)(request, "async_db.html", {"user_count": user_count})

0 commit comments

Comments
 (0)