How do I access user in Django Async view?
Asked Answered
D

3

9

I'm trying to access user but getting an error when the view is async.

Code:

from django.http import JsonResponse


async def archive(request):
    user = request.user
    return JsonResponse({'msg': 'success'})

error message:

django.myproject.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

What I tried:

from django.http import JsonResponse
from asgiref.sync import sync_to_async


async def archive(request):
    # user = sync_to_async(request.user)
    # user = sync_to_async(request.user)()
    # user = await sync_to_async(request.user)
    user = await sync_to_async(request.user)()
    return JsonResponse({'msg': 'success'})

Still getting the same error.

I want to access the user to check he/she has permission to archive a file.

EDIT: I eventually figured out that I had to move it into a temporary method and run that as sync_to_async. I did this below:

def _check_user(request):
    user = request.user
    ''' Logic here '''
    return

async def archive(request):
    await sync_to_async(_check_user, thread_sensitive=True)(request=request)
    ''' Logic here '''

And this seems to work, But not sure if this is the correct way of doing it?

Donte answered 10/3, 2021 at 10:3 Comment(0)
K
3

Try this:

from django.http import JsonResponse
from asgiref.sync import async_to_sync, sync_to_async

@sync_to_async
def archive(request):
    user = request.user
    return JsonResponse({'msg': 'success'})

I don't know if it's really async, I'm trying to fix this problem too.


I've found something: https://www.valentinog.com/blog/django-q/

If the first option not work, see this link.

Kerikeriann answered 19/3, 2021 at 13:49 Comment(1)
thank you the first option worked out nicely for what I needed to doDonte
S
2

The proper way to access user from an async view is:

from asgiref.sync import sync_to_async

from django.contrib import auth

async def myview(request):
    user = await sync_to_async(auth.get_user)(request)

Django 5.0 will add an .auser method to the request object.

Starstudded answered 5/7, 2023 at 13:58 Comment(0)
M
1

Since Django 5.0 you can use aget_user from the auth module

from django.contrib.auth import aget_user

async def archive(request):
    user = await aget_user(request)
    return JsonResponse({'msg': 'success'})
Marchant answered 15/4 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.