Django WebChat异步消费者报错:需使用线程或sync_to_async
解决Django异步Consumer中数据库查询的SynchronousOnlyOperation错误
错误原因是你在异步的websocket_connect方法中直接执行了同步的Django ORM查询操作,Django的ORM默认不支持在异步上下文里直接调用同步数据库操作,必须将其包装为异步兼容的形式。
要保留threads变量并修复错误,只需用asgiref.sync中的sync_to_async把同步的ORM查询包装成异步可执行的操作,修改后的代码如下:
from asgiref.sync import sync_to_async # 你的Consumer类 class YourConsumer(AsyncWebsocketConsumer): async def websocket_connect(self, event): print('connected', event) user = self.scope['user'] print(user.online) # 将同步ORM查询包装为异步操作并await获取结果 threads = await sync_to_async(Thread.objects.filter(participant__user=user).prefetch_related)() for thread in threads: chat_room = f'user_chatroom_{thread.id}' self.chat_room = chat_room await self.channel_layer.group_add( chat_room, self.channel_name ) await self.send({ 'type': 'websocket.accept' })
关键修改说明:
- 导入
sync_to_async工具函数,它负责把同步函数转换为异步函数 - 把原来的
Thread.objects.filter(...).prefetch_related()调用通过sync_to_async包裹,并且添加await关键字等待查询完成 - 其余逻辑保持不变,因为
channel_layer.group_add和self.send本身就是异步方法,无需修改
内容的提问来源于stack exchange,提问作者ken.1.n
相关产品推荐
相关产品推荐

