Home > Net >  Not allowed to call async on function converted with sync_to_async()
Not allowed to call async on function converted with sync_to_async()

Time:04-29

I am having problems with sync_to_async. I am getting the You cannot call this from an async context - use a thread or sync_to_async. error at the print statement, even though I used sync_to_async to convert the async function. If I do print(type(masters)) instead, i get a QuerySet as type. Is there something I am missing? I couldn't find this specific case on the docs.

Here is my code:

import discord
from discord.ext import commands
from asgiref.sync import sync_to_async


class Bot(commands.Bot):
    # ...
    async def on_message(self, msg):
        masters = await sync_to_async(self.subject.masters)()
        print(masters)

Here is the masters() function i'm trying to get results from:

from django.db import models


class Subject(models.Model):
    # ...
    def masters(self):
        from .subjectmaster import SubjectMaster
        return SubjectMaster.objects.filter(subject=self)

CodePudding user response:

Your QuerySet is not executed until it is printed and you print outside of the sync_to_async function. You need to evaluate the QuerySet in your method

class Subject(models.Model):

    def masters(self):
        from .subjectmaster import SubjectMaster
        # Force evaluation by converting to a list
        return list(SubjectMaster.objects.filter(subject=self))

An option, if you do not wish to return a list from the masters method is to run sync_to_async on the list function and pass it your queryset

masters = await sync_to_async(list)(self.subject.masters())
  • Related