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 в будущем.