访问Django消息页面弹出字典内容弹窗,如何排查解决?
Django消息页面显示字典内容问题解决
我是Django与Python初学者,跟着教程开发用户间消息功能时,访问消息页面会直接显示包含用户对象、时间、未读消息数的字典内容(示例:{'user': <User: test2>, 'last': datetime.datetime(2022, 12, 15, 20, 21, 19, 109214, tzinfo=datetime.timezone.utc), 'unread': 0})。试过设置USE_TZ=False、引入tz_detect解决时区问题,也尝试用JS隐藏,都没解决。
相关代码
urls.py
from django.urls import path from . import views as user_views app_name = 'chat' urlpatterns = [ path('messages/', user_views.inbox , name='messages'), path('messages/<username>', user_views.Directs , name='directs'), path('messages/send/', user_views.SendDirect , name='send_direct'), ]
views.py
from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from .models import Message from django.http import HttpResponse, HttpResponseBadRequest from django.template import loader from django.contrib.auth.models import User @login_required def inbox(request): messages = Message.get_messages(user=request.user) active_direct = None directs = None if messages: message = messages[0] active_direct = message['user'].username directs = Message.objects.filter(user=request.user, recipient=message['user']) directs.update(is_read=True) for message in messages: if message['user'].username == active_direct: message['unread'] = 0 context = { 'directs': directs, 'messages': messages, 'active_direct': active_direct, } template = loader.get_template('chat.html') return HttpResponse(template.render(context, request)) @login_required def Directs(request, username): user = request.user messages = Message.get_messages(user=user) active_direct = username directs = Message.objects.filter(user=user, recipient__username=username) directs.update(is_read=True) for message in messages: if message['user'].username == username: message['unread'] = 0 context = { 'directs': directs, 'messages': messages, 'active_direct': active_direct, } template = loader.get_template('chat.html') return HttpResponse(template.render(context, request)) @login_required def SendDirect(request): from_user = request.user to_user_username = request.POST.get('to_user') body = request.POST.get('body') if request.method == 'POST': to_user = User.objects.get(username=to_user_username) Message.send_message(from_user, to_user, body) return redirect('chat:messages') else: HttpResponseBadRequest()
模板 chat.html
<!DOCTYPE html> {% extends "base.html" %} {% load static %} {% block content %} <h1>Messages</h1> <div class="row"> <!-- Chats List --> <div class="col-3"> <div class="chatsList"> {% for message in messages %} <a class="{% if active_direct == message.user.username %}is-active{% endif %}" href=""></a> <div class="card h-100" style="width: 18rem;"> <div class="card-body"> {% if message.user.userinfo.userImage.url %} <div class="chatUserPic float-start"><img class="rounded-circle shadow-4-strong profileimg" src="{{ message.user.userinfo.userImage.url }}" height="75" width="75" alt="Profile Picture"></div> {% endif %} <div class="chatUserInfo"> <h5>{{ message.user.username }}</h5> <p></p> <a href="{% url 'chat:directs' message.user.username %}"><button type="button" class="float-end btn btn-success btn-sm">View Messages</button></a> </div> </div> </div> {% endfor %} </div> </div> <!-- Chat Window --> <div class="col"> {% for direct in directs %} <div class="card card-body"> <p class="text-start"><strong>{{ direct.sender.username }}</strong><small> on: {{ direct.date|date:'N d G:i' }}</small></p> {{ direct.body }} </div> {% endfor %} <!-- Chat Window --> <div> <form role="form" method="POST" action="{% url 'chat:send_direct' %}"> {% csrf_token %} <input type="hidden" name="to_user" value="{{ active_direct }}"> <div> <p class="control"> <textarea class="form-control float-start" name="body" rows="2" style="width: 30rem;" placeholder="Add a comment..." ></textarea> </p> </div> <div class="float-end"> <button type="submit" name="action" class="is-info btn btn-success btn-lg">Send</button> </div> </form> </div> </div> </div> {% endblock %}
models.py
from django.db import models from django.contrib.auth.models import User from django.db.models import Max from django.utils import timezone class Message(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user') sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='from_user') recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='to_user') body = models.TextField(max_length=500, blank=True, null=True) date = models.DateTimeField(default=timezone.now()) is_read = models.BooleanField(default=False) def send_message(from_user, to_user, body): sender_message = Message( user=from_user, sender=from_user, recipient=to_user, body=body, is_read=True) sender_message.save() recipient_message = Message( user=to_user, sender=from_user, body=body, recipient=from_user) recipient_message.save() return sender_message def get_messages(user): messages = Message.objects.filter(user=user).values('recipient').annotate(last=Max('date')).order_by('-last') users = [] for message in messages: users.append({ 'user': User.objects.get(pk=message['recipient']), 'last': message['last'], 'unread': Message.objects.filter(user=user, recipient__pk=message['recipient'], is_read=False).count() }) return users
问题分析与解决方案
核心问题
你看到的字典内容并非弹窗,而是模板渲染时不小心输出了message字典对象。检查模板代码,循环messages时存在无效空标签或遗留的测试变量输出,导致字典内容被渲染到页面上。
具体修复步骤
移除无效空链接
模板中循环里的空<a>标签无实际作用,直接删除或将激活样式移到卡片容器上:<!-- 原空链接 --> <!-- <a class="{% if active_direct == message.user.username %}is-active{% endif %}" href=""></a> --> <!-- 修改为带样式的卡片 --> <div class="card h-100 {% if active_direct == message.user.username %}is-active{% endif %}" style="width: 18rem;">清理空
<p>标签
模板中<h5>{{ message.user.username }}</h5>下方的空<p></p>可能是遗留的测试代码,直接删除该标签,避免意外渲染变量。改用Django标准视图返回方式
替换视图中手动加载模板的代码,使用render函数简化实现,避免潜在渲染异常:# 替换inbox和Directs视图中的返回代码 return render(request, 'chat.html', context)优化模型方法(可选)
将get_messages返回的字典列表改为数据类对象,提升代码可读性:from dataclasses import dataclass @dataclass class ChatPreview: user: User last: datetime.datetime unread: int def get_messages(user): messages = Message.objects.filter(user=user).values('recipient').annotate(last=Max('date')).order_by('-last') users = [] for message in messages: users.append(ChatPreview( user=User.objects.get(pk=message['recipient']), last=message['last'], unread=Message.objects.filter(user=user, recipient__pk=message['recipient'], is_read=False).count() )) return users
内容的提问来源于stack exchange,提问作者Dessy
相关产品推荐
相关产品推荐

