[英]Django Evaluate Queryset of ManyToMany relationship early to use in async function
I'm using a Django-Channels consumer for websocket async communication.我正在使用 Django-Channels 消费者进行 websocket 异步通信。
I have something like this below我在下面有这样的东西
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
I get a SynchronousOnlyOperation error when running this, right when it evaluates the queryset for Secrets in the ManyToMany field.运行此程序时,当它评估 ManyToMany 字段中 Secrets 的查询集时,我得到一个 SynchronousOnlyOperation 错误。
Is there a way to force the queryset to evaluate ahead of time in the synchronous get_command
function, instead of in the async websocket?有没有办法强制查询集在同步
get_command
函数中提前评估,而不是在异步 websocket 中? That way I can easily access the secrets via command.secrets
.这样我就可以通过
command.secrets
轻松访问这些秘密。
Currently, my workaround is to just handle the secrets as a separate variable目前,我的解决方法是将机密作为单独的变量处理
@sync_to_async
def get_command(pk):
command = Command.objects.get(id=pk)
secrets = list(command.secrets.all())
return command, secrets
Use prefetch_related
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related使用
prefetch_related
https://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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.