django async if else use a thread or sync_to_async

Question:

I don’t know where the error is.

I am using Django ORM asynchronously.

@database_sync_to_async
def filter_data(**kwargs):
    return FinishAnimateModel.objects.filter(**kwargs)
async def receive(self, text_data=None, bytes_data=None):
    ...
    if data['msg']:
        print('in')
        model = await DB.Myself.filter_data(name__contains='')
        print('ok')
    else:
        print('else')
        model = await DB.Myself.filter_data(name__contains='')
        print(model, 'model')

In if log

in
ok

In else log

else
You cannot call this from an async context - use a thread or sync_to_async.

I try to reverse if else.

async def receive(self, text_data=None, bytes_data=None):
    ...
    if not data['msg']:
        pass
    else:
        print('else')
        model = await DB.Myself.filter_data(name__contains='')
        print(model, 'model')

In else log

else
You cannot call this from an async context - use a thread or sync_to_async.

Why?

Can you help me?

Asked By: dudulu

||

Answers:

It looks like it could be passed in the if part only because you didn’t print(model) in there. If you do, then you should see the same problem.

However, I may not be able to answer the question you asked — It’s too little information.

All I can say is that the type returned by filter() is QuerySet, if you want to print it, you must convert it to list type.

Reference: Retrieving specific objects with filters

So, maybe you can modify it like this:

async def receive(self, text_data=None, bytes_data=None):
    ...
    if not data['msg']:
        print('in')
        model = list(await DB.Myself.filter_data(name__contains=''))
        print(model, 'ok')
    else:
        print('else')
        model = list(await DB.Myself.filter_data(name__contains=''))
        print(model, 'model')

Or

@database_sync_to_async
def filter_data(**kwargs):
    return list(FinishAnimateModel.objects.filter(**kwargs))
Answered By: LianSheng