Django の非同期 View の実装方法

記事
IT・テクノロジー
# はじめに
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
```

## ソースコードを修正
```python: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("htt://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!')
```

```python: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
```

## アクセスすると・・・
ブラウザから htt://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 htt://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)を使う必要がありますのでご注意ください。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す