Django 异步添加到多对多字段

问题描述 投票:0回答:1

我正在尝试使用这段代码来更新异步函数中的多对多字段:

async def get_last_message_id() -> int:
    last_message = await Message.objects.all().alast()
    if last_message:
        await last_message.read_by.aadd(request.user)
    return last_message.id if last_message else 0

但是,我收到以下错误:

TypeError: 'async_generator' object is not iterable

我在这里做错了什么?

谢谢!

django django-models django-views django-orm
1个回答
0
投票

该问题看起来与直接从异步函数调用同步 ORM 操作(

add
多对多字段)有关,而不使用 Django 的异步 ORM 功能或正确调整同步代码以异步运行。
Django 的 ORM 确实具有某些异步功能(“异步支持¶”),但并非 ORM 的所有部分都完全异步兼容。

考虑到 Django 异步 ORM 的限制,以及使用不带

add
前缀的
a
时收到的错误消息(表示尝试在异步上下文中执行同步操作),解决方案应涉及使用
sync_to_async来自 
asgiref.sync
 包装器 
用于异步执行同步代码。

from asgiref.sync import sync_to_async

async def get_last_message_id(request) -> int:
    last_message = await Message.objects.all().alast()
    if last_message:
        # Wrap the synchronous add operation in sync_to_async
        await sync_to_async(last_message.read_by.add)(request.user)
    return last_message.id if last_message else 0

sync_to_async(last_message.read_by.add)(request.user)
将同步
add
方法调用包装在
sync_to_async
中:它应该能够在异步函数中等待它。

但是...由于同步和异步执行之间的上下文切换,对单个操作使用

sync_to_async
可能会导致性能开销。

© www.soinside.com 2019 - 2024. All rights reserved.