As soon as I add async in front of a view, my template which contains {% if request.user.is_authenticated %}
causes a SynchronousOnlyOperation, You cannot call this from an async context - use a thread or sync_to_async.
The error only occurs when a user is logged in, hence is_authenticated==True. What am I not getting here?
view
async def test(request):
return render(request, 'test.html')
template, test.html
{% if request.user.is_authenticated %}
<script>
const usr = "{{user}}";
</script>
{% endif %}
CodePudding user response:
When the current user is not authenticated, request.user
is an AnonymousUser
, so is_authenticated
is just false. However, when request.user
is an actual user, it needs to check through the ORM if the user is authenticated. The ORM is synchronous (except in a few situations), so this doesn't work in an async context. To make this work, use sync_to_async
in the view:
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)()})
And in test.html
:
{% if is_authenticated %}
<script>
const usr = "{{user}}";
</script>
{% endif %}
I know it's a pain, but for now it's the only way. Here's hoping that Django will add asynchronous support ORM-wide in the next release.