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

访问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时存在无效空标签或遗留的测试变量输出,导致字典内容被渲染到页面上。

具体修复步骤

  1. 移除无效空链接
    模板中循环里的空<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;">
    
  2. 清理空<p>标签
    模板中<h5>{{ message.user.username }}</h5>下方的空<p></p>可能是遗留的测试代码,直接删除该标签,避免意外渲染变量。

  3. 改用Django标准视图返回方式
    替换视图中手动加载模板的代码,使用render函数简化实现,避免潜在渲染异常:

    # 替换inbox和Directs视图中的返回代码
    return render(request, 'chat.html', context)
    
  4. 优化模型方法(可选)
    将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:01:18