Django: Невозможно присвоить "'username'": "Message.sender" должен быть экземпляром "User".

Я довольно новичок в Django / каналах, поэтому прошу прощения, если здесь не показано все необходимое. Я буду рад предоставить дополнительную информацию, если это необходимо.

Как бы то ни было, я работаю над приложением для чата один на один и столкнулся с такой ошибкой:

ValueError: Cannot assign "'admin'": "Message.sender" must be a "UserProfileModel" instance.

This issue is that I thought admin was an instance of my user model? admin is the username of my superuser, which is logged in as I get this error. When I try to change the admin input to self.scope['user] I then get a serialization error. Any help is appreciated.

Здесь представлен мой файл consumers.py:

import json
from channels.generic.websocket import WebsocketConsumer
from django.conf import settings (unused)
from accounts.models import UserProfileModel
from asgiref.sync import async_to_sync
from chat.models import Thread, Message

class ChatConsumer(WebsocketConsumer):

    def create_chat(self, msg, sender):
        new_msg = Message.objects.create(sender=sender, text=msg)
        new_msg.save()
        return new_msg


    def connect(self):

        self.me = self.scope['user']
        self.user_name = self.scope['url_route']['kwargs']['room_name']
        self.you = UserProfileModel.objects.get(username=self.user_name)

        self.thread_obj = Thread.objects.get_or_create_personal_thread(self.me, self.you)
        self.room_group_name = f'personal_thread_{self.thread_obj.id}'

        # Join room group
        async_to_sync(self.channel_layer.group_add)(
        self.room_group_name,
        self.channel_name
        )

        self.accept()
        print(f'[{self.channel_name}] [{self.room_group_name}] connected')


    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )


    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data) # WHAT IS TEXT_DATA REFERRING TO?

        message = text_data_json['message']
        # DOES A SENDER NEED TO GO INSIDE TEXT_DATA?
    
        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message,
                'sender' : self.scope['user'].username #THIS SEEMS TO BE THE ROOT OF THE ISSUE | DOES THE SENDER FROM JSON NEED TO GO HERE
        }
    )
    

    # Receive message from room group
    def chat_message(self, event):
        message = event['message']
        sender = event['sender']
        new_msg = self.create_chat(msg=message, sender=sender)
    
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': new_msg.msg,
            'sender' : new_msg.sender
        }))

models.py

from django.conf import settings
from chat.managers import ThreadManager
from django.db import models

class TrackingModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    class Thread(TrackingModel):
    THREAD_TYPE = (
        ('personal', 'Personal'),
        ('group', 'Group')
    )

    name = models.CharField(max_length=50, null=True, blank=True)
    thread_type = models.CharField(max_length=15, choices=THREAD_TYPE, default='group')
    users = models.ManyToManyField(settings.AUTH_USER_MODEL)

    objects = ThreadManager()

    def __str__(self) -> str:
        if self.thread_type == 'personal' and self.users.count() == 2:
            return f'{self.users.first()}' and f'{self.users.last()}'
        return f'{self.name}'

    class Message(TrackingModel):
    thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
    sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    text = models.TextField(blank=False, null=False)

    def __str__(self) -> str:
        return f'From <Thread - {self.thread}>'

managers.py

from django.db import models
from django.db.models import Count

class ThreadManager(models.Manager):
    def get_or_create_personal_thread(self, user1, user2):
        threads = self.get_queryset().filter(thread_type='personal')
        threads = threads.filter(users__in=[user1, user2]).distinct()
        threads = threads.annotate(u_count=Count('users')).filter(u_count=2)
        if threads.exists():
            return threads.first()
        else:
            thread = self.create(thread_type='personal')
            thread.users.add(user1)
            thread.users.add(user2)
            return thread

    def by_user(self, user):
        return self.get_queryset().filter(users__in=[user])

views.py

from django.shortcuts import render

# Create your views here.
def index(request): #Change to IndexView
    return render(request, 'chat/chatindex.html')

def room(request, room_name): #Change to RoomView
    return render(request, 'chat/chatroom.html', {
        'room_name': room_name
    })
Вернуться на верх