Skip to content

Commit

Permalink
Add asynchronous examples (django-commons#1819)
Browse files Browse the repository at this point in the history
  • Loading branch information
salomvary committed Sep 19, 2023
1 parent c911d73 commit 49624ea
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 1 deletion.
10 changes: 10 additions & 0 deletions example/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ environment variable::

$ DB_BACKEND=postgresql python example/manage.py migrate
$ DB_BACKEND=postgresql python example/manage.py runserver

Using an asynchronous (ASGI) server:

Install [Daphne](https://pypi.org/project/daphne/) first:

$ python -m pip install daphne

Then run the Django development server:

$ ASYNC_SERVER=true python example/manage.py runserver
9 changes: 9 additions & 0 deletions example/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""ASGI config for example project."""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")

application = get_asgi_application()
25 changes: 25 additions & 0 deletions example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# Application definition

INSTALLED_APPS = [
*(["daphne"] if os.getenv("ASYNC_SERVER", False) else []),
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
Expand Down Expand Up @@ -60,6 +61,7 @@
USE_TZ = True

WSGI_APPLICATION = "example.wsgi.application"
ASGI_APPLICATION = "example.asgi.application"

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

Expand Down Expand Up @@ -97,3 +99,26 @@
}

STATICFILES_DIRS = [os.path.join(BASE_DIR, "example", "static")]

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {
"class": "logging.StreamHandler",
},
},
"root": {
"handlers": ["console"],
"level": "WARNING",
},
"loggers": {
# Log when an asynchronous handler is adapted for middleware.
# See warning here: https://docs.djangoproject.com/en/4.2/topics/async/#async-views
"django.request": {
"handlers": ["console"],
"level": os.getenv("DJANGO_REQUEST_LOG_LEVEL", "INFO"),
"propagate": False,
},
},
}
14 changes: 14 additions & 0 deletions example/templates/async_db.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Async DB</title>
</head>
<body>
<h1>Async DB</h1>
<p>
<span>Value </span>
<span>{{ user_count }}</span>
</p>
</body>
</html>
5 changes: 4 additions & 1 deletion example/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
from django.urls import include, path
from django.views.generic import TemplateView

from example.views import increment
from example.views import async_db, async_db_concurrent, async_home, increment

urlpatterns = [
path("", TemplateView.as_view(template_name="index.html"), name="home"),
path("async/", async_home, name="async_home"),
path("async/db/", async_db, name="async_db"),
path("async/db-concurrent/", async_db_concurrent, name="async_db_concurrent"),
path("jquery/", TemplateView.as_view(template_name="jquery/index.html")),
path("mootools/", TemplateView.as_view(template_name="mootools/index.html")),
path("prototype/", TemplateView.as_view(template_name="prototype/index.html")),
Expand Down
25 changes: 25 additions & 0 deletions example/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import asyncio

from asgiref.sync import sync_to_async
from django.contrib.auth.models import User
from django.http import JsonResponse
from django.shortcuts import render


def increment(request):
Expand All @@ -8,3 +13,23 @@ def increment(request):
value = 1
request.session["value"] = value
return JsonResponse({"value": value})


async def async_home(request):
return await sync_to_async(render)(request, "index.html")


async def async_db(request):
user_count = await User.objects.acount()

return await sync_to_async(render)(request, "async_db.html", {"user_count": user_count})


async def async_db_concurrent(request):
# Do database queries concurrently
(user_count, _) = await asyncio.gather(
User.objects.acount(),
User.objects.filter(username="test").acount()
)

return await sync_to_async(render)(request, "async_db.html", {"user_count": user_count})

0 comments on commit 49624ea

Please sign in to comment.