Django 3.1 - асинхронные представления - работа с наборами запросов

Начиная с версии 3.1 (в настоящее время бета) Django поддерживает асинхронные представления.

async def myview(request):
    users = User.objects.all()

Этот пример не будет работать, поскольку ORM еще не готов для асинхронной обработки.

так каков текущий обходной путь?

вы не можете просто использовать sync_to_async с набором запросов - поскольку они не оцениваются:

from asgiref.sync import sync_to_async

async def myview(request):
    users = await sync_to_async(User.objects.all)()

поэтому единственный способ - оценить набор запросов внутри sync_to_async:

async def myview(request):
    users = await sync_to_async(lambda: list(User.objects.all()))()

что выглядит очень некрасиво

есть мысли как сделать приятнее?

2 ответа

Существует обычная GOTCHA: наборы запросов Django лениво оцениваются (запрос к базе данных выполняется только при запуске итерации):

поэтому вместо этого - используйте оценку (со списком):

from asgiref.sync import sync_to_async

async def myview(request):
    users = await sync_to_async(list)(User.objects.all())

Из Джанго 4.1 async forподдерживается во всех QuerySet:

      async def myview(request):
    async for user in User.objects.all():
        ...

дополнительная информация: ссылка

Другие вопросы по тегам