You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Channels实时聊天发送消息后如何无刷新展示用户头像

解决方案

问题根源

你当前代码中使用的{{ message.author.profile.image.url }}是Django模板在页面首次加载时就渲染完成的静态固定值,不会跟随后续WebSocket接收到的不同用户消息动态更新,因此无法匹配每个发信用户的头像。

修改步骤

1. 修改Consumers.py,在消息推送时携带对应用户头像URL

你需要在异步逻辑中查询发信用户的头像地址,并随消息一起推送给前端,修改后代码如下:

import json
from channels.db import sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer
from django.contrib.auth.models import User
from .models import Message

class ChatRoomConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        print(self.room_group_name)

        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # 新增同步方法:根据用户名获取用户头像URL
    @sync_to_async
    def get_user_avatar(self, username):
        user = User.objects.get(username=username)
        return user.profile.image.url

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        username = text_data_json['username']
        room = text_data_json['room']

        await self.save_message(username, room, message)
        # 获取发信用户的头像URL
        avatar_url = await self.get_user_avatar(username)

        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chatroom_message',
                'message': message,
                'username': username,
                'avatar_url': avatar_url, # 新增头像字段
            }
        )

    async def chatroom_message(self, event):
        message = event['message']
        username = event['username']
        avatar_url = event['avatar_url'] # 取出头像字段

        await self.send(text_data=json.dumps({
            'message': message,
            'username': username,
            'avatar_url': avatar_url, # 推送给前端
        }))

    @sync_to_async
    def save_message(self, username, room, message):
        user = User.objects.get(username = username)
        Message.objects.create(author = user, room = room, content = message)

2. 修改前端JavaScript代码,动态渲染头像

将原来的静态模板变量替换为WebSocket返回的动态头像地址,同时注意不要给多个头像设置重复的id,修改onmessage逻辑即可:

chatSocket.onmessage = function (e) {
    const data = JSON.parse(e.data);
    console.log(data)
    if (data.message) {
        // 用模板字符串插入后端返回的头像地址,id改为class避免重复
        document.querySelector('#chat-text').innerHTML += (`<img class="chat-avatar" src="${data.avatar_url}" alt="${data.username}"> ${data.username}<br>${data.message}<br>`);
    }
}

修改完成后发送消息即可实时加载对应用户的头像,无需刷新页面。

内容的提问来源于stack exchange,提问作者IceSpeaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 01:03:01