Async Django: переходим на ASGI и adrf
Зачем ASGI
WSGI (Gunicorn) обрабатывает каждый запрос в отдельном потоке. При 100 одновременных запросах нужно 100 потоков. ASGI (uvicorn) использует event loop — тысячи соединений в одном потоке при правильном async-коде.
Переход на ASGI
В settings.py ничего менять не нужно. Меняем wsgi.py на asgi.py:
# config/asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_asgi_application()
Запуск:
uvicorn config.asgi:application --host 0.0.0.0 --port 8000 --workers 4
adrf для ViewSet
Стандартный DRF не поддерживает async. Используем adrf:
pip install adrf
from adrf.viewsets import ModelViewSet
class NoteViewSet(ModelViewSet):
async def list(self, request):
notes = [n async for n in Note.objects.filter(status='published')]
...
Async ORM
Django 4.1+ поддерживает async ORM нативно:
note = await Note.objects.aget(slug=slug)
notes = [n async for n in Note.objects.filter(status='published')]
note = await Note.objects.acreate(title='Test', content='...')
Подводные камни
Нельзя вызывать синхронный ORM из async-контекста — получишь SynchronousOnlyOperation. Если нужно — оборачивай в sync_to_async:
from asgiref.sync import sync_to_async
get_note = sync_to_async(Note.objects.get)
note = await get_note(slug=slug)
Middleware тоже должны быть async — иначе Django переключается в sync-режим для всего запроса.