はじめに
Django 3.1 より非同期 Viewがサポートされるようになりました。
非同期で描画することによって、Webアプリケーションのページ速度の向上が見込めます。Python標準に入っているasyncやthread,multiprocessingとは違う技術が使われているので、Webアプリケーション+Djangoの構成においては非同期 Viewを使った方が良いかもしれません。
環境
モジュール | バージョン |
---|---|
Python | 3.8.3 |
Django | 3.1.3 |
httpx | 0.16.1 |
uvicorn | 0.11.8 |
使い方
App の作成
$ django-admin.py startproject project .
$ python manage.py startapp app
ソースコードを修正
view.py
import asyncio
import httpx
from django.http import HttpResponse
async def http_call_async():
for num in range(1, 6):
await asyncio.sleep(0.5)
print(num)
async with httpx.AsyncClient() as client:
r = await client.get("https://www.yahoo.co.jp/")
print(r)
async def index(request):
loop = asyncio.get_event_loop()
loop.create_task(http_call_async())
return HttpResponse('Hello, async world!')
urls.py
from django.contrib import admin
from django.urls import path
from app.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index)
]
実行
$ uvicorn project.asgi:application
アクセスすると・・・
ブラウザから http://127.0.0.1:8000 にアクセスすると、
$ uvicorn project.asgi:application
INFO: Started server process [89162]
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:52036 - "GET / HTTP/1.1" 200 OK
Not Found: /favicon.ico
INFO: 127.0.0.1:52036 - "GET /favicon.ico HTTP/1.1" 404 Not Found
1
2
3
4
5
<Response [200 OK]>
のように出力され、先に 200 OK が返っている事が分かるかと思います。
おわりに
いかがでしたでしょうか?試すだけであれば、比較的簡単に試せたかと思います。
複数のAPIにリクエストを投げてviewを返す時など非同期でリクエストしてあげる事でボトルネックとなりがちなネットワーク関連の処理を
軽減させる事ができます。
また、Django を実行する際は、runserver ではなく、ASGI(Asynchronous Server Gateway Interface)を使う必要がありますのでご注意ください。
参考
https://testdriven.io/blog/django-async-views/
https://docs.djangoproject.com/en/3.1/topics/async/