You cannot call this from an async context - use a thread or sync_to_async
Django выдает ошибку на consumers.py: django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async
from .models import Room, Message
class ChatConsumer(AsyncWebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
self.room_name = None
self.room_group_name = None
self.room = None
self.user = None
self.user_inbox = None
async def connect(self):
self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
self.room_group_name = "chat_%s" % self.room_name
self.room = sync_to_async(Room.objects.get(name=self.room_name))
self.user = self.scope["user"]
self.user_inbox = f"inbox_{self.user.username}"
# Join room group
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
await self.accept()
self.send(
json.dumps(
{
"type": "user_list",
"users": [user.username for user in self.room.online.all()],
}
)
)
if self.user.is_authenticated:
await self.channel_layer.group_add(
self.user_inbox,
self.channel_name,
)
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "user_join",
"user": self.user.username,
},
)
self.room.online.add(self.user)
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
if self.user.is_authenticated:
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "user_leave",
"user": self.user.username,
},
)
self.room.online.remove(self.user)
async def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)
message = text_data_json["message"]
if not self.user.is_authenticated:
return
if message.startswith("/pm "):
split = message.split(" ", 2)
target = split[1]
target_msg = split[2]
await self.channel_layer.group_send(
f"inbox_{target}",
{
"type": "private_message",
"user": self.user.username,
"message": target_msg,
},
)
self.send(
json.dumps(
{
"type": "private_message_delivered",
"target": target,
"message": target_msg,
}
)
)
return
await self.channel_layer.group_send(
self.room_group_name, {"type": "chat_message", "user": self.user.username, "message": message},
)
sync_to_async(Message.objects.create(user=self.user, room=self.room, content=message))
def chat_message(self, event):
self.send(text_data=json.dumps(event))
def user_join(self, event):
self.send(text_data=json.dumps(event))
def user_leave(self, event):
self.send(text_data=json.dumps(event))
def private_message(self, event):
self.send(text_data=json.dumps(event))
def private_message_delivered(self, event):
self.send(text_data=json.dumps(event))