Django: асинхронное приложение из одного файла
Django 3.0 alpha 1 вышел на этой неделе. Он вводит поддержку ASGI благодаря большой тяжелой работе Эндрю Годвина.
Вот как его можно попробовать самостоятельно.
Сначала создайте новую виртуальную среду (я использую Python 3.7.4) и установите пакеты:
$ python -m venv venv $ source venv/bin/activate $ pip install django==3.0a1 daphne==2.3.0
Затем создайте новый файл app.py
:
import html import os import sys from django.conf import settings from django.core.asgi import get_asgi_application from django.http import HttpResponse from django.urls import path from django.utils.crypto import get_random_string settings.configure( DEBUG=(os.environ.get("DEBUG", "") == "1"), # Отключить проверку заголовка хоста ALLOWED_HOSTS=["*"], ROOT_URLCONF=__name__, # Мы не используем никаких функций безопасности, но Django требует этот параметр SECRET_KEY=get_random_string(50), ) def index(request): name = request.GET.get("name", "World") return HttpResponse(f"Hello, {html.escape(name)}!") urlpatterns = [path("", index)] application = get_asgi_application() if __name__ == "__main__": from django.core.management import execute_from_command_line execute_from_command_line(sys.argv)
Затем запустите его под Daphne:
$ daphne app:application
Зайдите в ваш браузер на url http://localhost:8000/?name=Django%20user
, чтобы увидеть «Hello, Django user!»
Асинхронная поддержка в Django 3.0 является первым шагом и ограничена уровнем внешнего обработчика. Промежуточное программное обеспечение, представления, ORM и все, к чему вы привыкли в Django, остается синхронным. Обработчик ASGI достигает этого путем запуска генерации ответов в пуле потоков.
Если вы хотите использовать Websockets, вам понадобится второй фреймворк, например, Channels или Starlette .
ASGI - это простой интерфейс с подходом «turtles all the way down». Это позволяет нам связать наше приложение Django с другим приложением «middleware»:
django_application = get_asgi_application() websocket_application = # TODO: make it async def application(scope, receive, send): if scope['type'] == 'http': await django_application(scope, receive, send) elif scope['type'] == 'websocket': await websocket_application(scope, receive, send) else: raise NotImplementedError(f"Unknown scope type {scope['type']}")
Поддержка ASGI будет увеличиваться с выходом новых версий Django. DEP 9 описывает план Эндрю по увеличению поддержки ASGI в будущем.