Теги шаблонов django с асинхронным представлением

Как только я добавляю async перед представлением, мой шаблон, содержащий {% if request.user.is_authenticated %}, вызывает SynchronousOnlyOperation, Вы не можете вызвать это из контекста async - используйте поток или sync_to_async.

Ошибка возникает только тогда, когда пользователь вошел в систему. Что я не понимаю?

view

async def test(request):
    return render(request, 'test.html')

шаблон, test.html

{% if request.user.is_authenticated %}
<script>
  const usr = "{{user}}";
</script>
{% endif %}

Когда текущий пользователь не аутентифицирован, request.user является AnonymousUser, поэтому is_authenticated будет просто false. Однако, когда request.user является реальным пользователем, необходимо проверить через ORM, аутентифицирован ли пользователь. ORM является синхронным (за исключением некоторых ситуаций), поэтому в асинхронном контексте это не работает. Чтобы заставить это работать, используйте sync_to_async в представлении:

from asgiref.sync import sync_to_async
async def test(request):
    return render(request, 'test.html', {"is_authenticated": await sync_to_async(lambda: request.user.is_authenticated)})

И в test.html:

{% if is_authenticated %}
<script>
  const usr = "{{user}}";
</script>
{% endif %}

Я знаю, что это боль, но пока это единственный способ. Остается надеяться, что Django добавит асинхронную поддержку ORM в следующем релизе.

Вернуться на верх