Django Channels WebSocket Consumer 中未定义的用户名问题

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

我创建了 djangoconsumers.py 和一个 html 和 css 前端来显示用户发送的消息、发件人的个人资料图片和发件人的用户名,但每当我打开浏览器时,消息显示良好,但用户名出现作为未定义的。例如@Undefined:你好吗

这是我的消费者.py

`User = get_user_model()

class DiscussionRoomConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f"discussion_room_{self.room_name}"

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

        await self.accept()

        # Get or create the VirtualRoom instance based on the provided room_name
        virtual_room = await self.get_virtual_room()

        if virtual_room is not None:
            # Send existing messages and old messages to the new user
            old_messages = await self.get_old_messages(virtual_room)
            for message in old_messages:
                await self.send(text_data=json.dumps({
                    'message': message['content'],
                    'user_id': message['user'],
                    'user_picture': await self.get_user_profile_picture(message['user']),
                }))

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

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        user_id = self.scope["user"].id

        # Get the VirtualRoom instance based on the extracted room name asynchronously
        virtual_room = await self.get_virtual_room()

        # Check if the VirtualRoom instance exists
        if virtual_room:
            # Save message to the database with the VirtualRoom instance asynchronously
            await self.save_interaction_to_database(user_id, virtual_room, message)

            # Send message to the room group
            user_picture = await self.get_user_profile_picture(user_id)
            await self.channel_layer.group_send(
                self.room_group_name,
                {
                    'type': 'chat.message',
                    'message': message,
                    'user_id': user_id,
                    'user_picture': user_picture,
                }
            )
        else:
            # Handle the case where the VirtualRoom does not exist
            print(f"VirtualRoom with slug '{self.room_name}' does not exist.")


    # Receive message from the room group
    async def chat_message(self, event):
        message = event['message']
        user_id = event['user_id']
        user_picture = event['user_picture']

        # Send the message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message,
            'user_id': user_id,
            'user_picture': user_picture,
        }))`


and this is my frontend:
<!DOCTYPE html>
{% load static %}
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{% static 'css/discussionroom.css' %}">
    <title>Discussion Room</title>
</head>
<body>
<div id="discussion-room">
    <div id="chat-box">
        {% for message in messages %}
            <div>
                <img src="{{ message.user_picture.url|default:'/static/images/avatar.svg' }}" alt="User Picture" style="width: 30px; height: 30px;">
                <strong>{{ message.username }}:</strong>
                {{ message.message }}
            </div>
        {% endfor %}
    </div>

    <input type="text" id="message-input" placeholder="Type your message...">
    <button onclick="sendMessage()">Send</button>
</div>

<script>
    // Get the room name from the URL
    const pathArray = window.location.pathname.split('/');
    const roomNameIndex = pathArray.indexOf('discussions') + 1;
    const roomName = pathArray[roomNameIndex].split('@')[1];

    // Log the extracted room name
    console.log('Extracted room name:', roomName);

    // Create a new WebSocket connection
    const socket = new WebSocket(`ws://${window.location.host}/ws/discussions/${roomName}/`);

    socket.onmessage = function(event) {
        const data = JSON.parse(event.data);
        displayMessage(data.user_picture, data.message);
    };

    function sendMessage() {
        const message = document.getElementById('message-input').value;
        if (message.trim() !== '') {
            socket.send(JSON.stringify({'message': message}));
            document.getElementById('message-input').value = '';
        }
    }
    function displayMessage(userPicture, message) {
    console.log('Received user picture:', userPicture);

    const messageDiv = document.createElement('div');

    // Set the userPicture URL
    const imageUrl = userPicture || '/static/images/avatar.svg';

    //console.log('Selected image URL:', imageUrl);

    const imgElement = new Image();
    imgElement.src = imageUrl;

    // Add an event listener to handle image load errors
    imgElement.addEventListener('error', function() {
        //console.warn('Error loading image. Using default avatar.');
        messageDiv.innerHTML = `<img src="/static/images/avatar.svg" alt="Default Avatar" style="width: 30px; height: 30px;"> ${message}`;
        document.getElementById('chat-box').appendChild(messageDiv);
    });

    // Add an event listener to handle image load success
    imgElement.addEventListener('load', function() {
        imgElement.className = 'user-profile-img'; // Add this line
        messageDiv.innerHTML = `<img src="${imageUrl}" alt="User Picture" style="width: 30px; height: 30px;  border-radius: 50%; object-fit: cover; "> ${message}`;
        document.getElementById('chat-box').appendChild(messageDiv);
    });
}

</script>

</body>
</html>

javascript python django websocket channel
1个回答
0
投票

为了获取用户模型,您需要在 的 connect 函数中使用 user= self.scope["user"]

加入我们的 Discord 服务器,我们在 django 和应用程序开发中工作,并做一些很酷的项目

https://discord.com/invite/yQxDSSevc8

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