如何在外部JS文件中使用Django标签并渲染数据库聊天消息
聊天弹窗实现与Django数据传递方案
问题描述
需要通过jQuery在元素点击时向页面body追加聊天弹窗,并显示数据库中的历史消息。当前在外部JS文件中编写的代码包含Django模板标签,但Django标签无法在外部JS文件中解析,代码如下:
chatPopup = '<div class="message_box" style="right:290px" rel="'+ userID+'"><div class="message_header" rel="'+ userID+'">'+ '<img src="http://127.0.0.1:8000'+pro+'" class="user_icon"><h3 class="username">'+username+'</h3>'+ '<i class="fa fa-times close" rel="'+ userID+'"></i></div><hr><div class="message_content"><div class="messages" rel="'+ userID+'">'+ '{% for chat in thread.chatmessage_thread.all %}'+ '<div class="chat">'+ '{% if chat.user == user %}'+ '<div class="new_messages p2">{{ chat.message }}</div>'+ '{% else %}'+ '<div class="new_messages p1">{{ chat.message }}</div>'+ '{% endif %}</div>{% endfor %}</div><div class="input_box">'+ '<textarea type="text" class="message_input" rel="'+ userID+'" placeholder="Type Message..."></textarea>'+ '<i class="fa fa-arrow-circle-right enter" rel="'+ userID+'"></i></div></div></div>'; if ( $('[rel="'+userID+'"]').length == 0) { $("body").append( chatPopup ); }
需要将Django变量thread.chatmessage_thread.all传递到外部JS文件中,实现动态渲染历史消息。
解决方案
核心思路是在Django HTML模板中将数据转换为JSON格式,传递给全局变量,再在外部JS文件中读取该数据并动态生成消息内容。
步骤1:在HTML模板中传递Django数据
在加载外部JS文件之前,将聊天历史数据和当前用户信息转换为JSON,存入全局变量或通过json_script标签注入:
<!-- 在HTML模板的<body>标签内,外部JS引入之前添加 --> <script> // 传递当前用户ID(用于判断消息发送方) window.currentUserID = {{ user.id|safe }}; </script> <!-- 使用Django内置的json_script标签安全注入聊天数据 --> {{ thread.chatmessage_thread.all|json_script:"chat-history" }} <!-- 引入外部JS文件 --> <script src="/path/to/your/external.js"></script>
步骤2:修改外部JS文件,动态生成弹窗
在外部JS文件中,读取全局的聊天数据,替换原有的Django模板标签逻辑:
// 外部JS文件中的弹窗生成函数 function renderChatPopup(userID, pro, username) { // 从页面中读取聊天历史数据 const chatHistory = JSON.parse(document.getElementById('chat-history').textContent); // 动态生成消息列表HTML let messagesHtml = ''; chatHistory.forEach(chat => { // 判断消息是否为当前用户发送,添加对应的样式类 const messageClass = chat.user_id === window.currentUserID ? 'new_messages p2' : 'new_messages p1'; messagesHtml += `<div class="chat"><div class="${messageClass}">${chat.message}</div></div>`; }); // 拼接完整的弹窗HTML const chatPopup = ` <div class="message_box" style="right:290px" rel="${userID}"> <div class="message_header" rel="${userID}"> <img src="http://127.0.0.1:8000${pro}" class="user_icon"> <h3 class="username">${username}</h3> <i class="fa fa-times close" rel="${userID}"></i> </div> <hr> <div class="message_content"> <div class="messages" rel="${userID}">${messagesHtml}</div> <div class="input_box"> <textarea type="text" class="message_input" rel="${userID}" placeholder="Type Message..."></textarea> <i class="fa fa-arrow-circle-right enter" rel="${userID}"></i> </div> </div> </div> `; // 避免重复添加弹窗 if ($(`[rel="${userID}"]`).length === 0) { $("body").append(chatPopup); } }
关键说明
- 使用
json_script标签是Django官方推荐的安全方式,可自动处理转义,避免XSS攻击风险 - 需要确保
chatmessage_thread模型中包含user_id字段(或可通过序列化获取用户标识),用于判断消息发送方 - 调用
renderChatPopup函数时,需传入对应的userID、pro(头像路径)、username参数
内容的提问来源于stack exchange,提问作者sodmzs1
相关产品推荐
相关产品推荐

