我正在开发 Django 网络聊天。我刚刚切换了数据库结构以支持群聊。到目前为止,我更改了代码,并且正在努力找出如何修复以下错误。
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
这是我来自consumers.py的websocket_connect
async def websocket_connect(self, event):
print('connected', event)
user = self.scope['user']
print(user.online)
threads = 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'
})
我对每一个答案都很高兴!
我尝试更改线程变量,但我无法更改它,因为我需要它。
现在(暂时)修复了它。这可能不是最好的解决方案,但这对我有帮助。
import os
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
希望我能帮忙,如果有更好的解决方案,请纠正我。
如 Django 文档此处中所述,从异步函数运行阻塞同步查询代码可能会引发
SynchronousOnlyOperation
,以免阻塞事件循环。
某些查询方法有异步版本,例如
get
有其异步版本 aget
,但是 没有 afilter
。但是,您可以使用 async for
迭代查询对象。因此,要迭代代码片段中的变量 threads
,请将 for thread in threads
替换为 async for thread in threads
:
async def websocket_connect(self, event):
print('connected', event)
user = self.scope['user']
print(user.online)
threads = Thread.objects.filter(participant__user=user).prefetch_related()
async for thread in threads: # async iteration
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'
})