Từ Django 3.1, view có thể là async def.
Lợi rõ khi view chờ I/O nhiều — gọi external API, đọc nhiều endpoint song song, WebSocket.
python
import asyncio
import httpx
from django.http import JsonResponse
async def aggregate(request):
async with httpx.AsyncClient() as client:
a, b = await asyncio.gather(
client.get('https://api.x/users'),
client.get('https://api.y/posts'),
)
return JsonResponse({'users': a.json(), 'posts': b.json()})Rào cản lớn nhất là ORM.
- Django ORM bản chất là sync — gọi
Post.objects.filter(...)trong async view sẽ bịSynchronousOnlyOperation. - Phải dùng async variant:
await Post.objects.aget(...),await Post.objects.acreate(...),async for post in Post.objects.all(), hoặc wrap bằngsync_to_async(...). - Driver Postgres mặc định (
psycopg2) cũng là sync, nên Django chạy ORM trong threadpool chứ không phải event loop thực sự. - Driver async thật sự là
psycopg3(Django 4.2+ support một phần).
python
async def view(request):
posts = []
async for post in Post.objects.all()[:10]:
posts.append({'id': post.id, 'title': post.title})
return JsonResponse({'posts': posts})Đừng đổi mọi view sang async vì "nghe có vẻ nhanh hơn".
- Sync view dưới Gunicorn
gthreadxử lý 90% case rất ổn. - Async chỉ thắng rõ khi đợi nhiều I/O song song; query DB tuần tự thì sync còn nhanh hơn vì không có overhead event-loop hop.