Django计算多多关系的Queryset,以便在异步函数中使用



我正在使用Django-Channels消费者来进行websocket异步通信。

我在

下面有这样的内容

class Command(UUIDModel):
owner = models.ForeignKey(AUTH_USER_MODEL, default=None, on_delete=models.SET_DEFAULT, null=True, blank=True, related_name='commands')
name = models.CharField('Name', default='New Command', max_length=128, blank=True, null=True)

class Secret(UUIDModel):
owner = models.ForeignKey(AUTH_USER_MODEL, default=None, on_delete=models.SET_DEFAULT, null=True, blank=True, related_name='secrets')
command = models.ManyToManyField(Command, blank=True, related_name='secrets')

@sync_to_async
def get_command(pk):
command = Command.objects.get(id=pk)
return command

class CommandConsumer(AsyncWebsocketConsumer):
@log_exceptions
async def command(self, event):
log.debug(event)
command = await get_command(event.get('command').get('id'))
log.debug(command)
log.debug(command.secrets)
log.debug(command.secrets.all())  # Fails here
return

我得到一个SynchronousOnlyOperation错误时运行这个,正确的时候,它在manymany字段中评估秘密的查询集。

是否有一种方法可以强制查询集在同步get_command函数中提前评估,而不是在异步websocket中?这样我就可以很容易地通过command.secrets访问机密。

目前,我的解决方法是将秘密作为一个单独的变量

来处理。
@sync_to_async
def get_command(pk):
command = Command.objects.get(id=pk)
secrets = list(command.secrets.all())
return command, secrets

使用prefetch_relatedhttps://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related

@sync_to_async
def get_command(pk):
command = Command.objects.prefetch_related("secrets").get(id=pk)
return command

class CommandConsumer(AsyncWebsocketConsumer):
@log_exceptions
async def command(self, event):
log.debug(event)
command = await get_command(event.get('command').get('id'))
log.debug(command)
log.debug(command.secrets)
log.debug(command.secrets.all())  # No longer fails
return

最新更新