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

Django内置消息框架异常:成功与错误消息样式混淆排查

Django消息框架样式颠倒问题解决方案

问题描述

开发Django项目时,使用内置消息框架展示成功与错误消息,出现样式颠倒异常:成功消息显示错误样式,错误消息显示成功样式。

相关代码

HTML模板代码

{% extends 'base.html' %}
{% load widget_tweaks %}
{% block content %}
<div class="mx-auto max-w-screen-xl px-4 py-16 sm:px-6 lg:px-8">
    <div class="mx-auto max-w-lg">
      {% if messages %}
        {% for message in messages %}
            {% if message.tags == 'success' %}
                <div class="rounded border-s-4 mb-1 border-green-500 bg-emerald-50 p-4">
                  <strong class="block font-medium text-green-800"> Successfully </strong>
                
                  <p class="mt-2 text-sm text-green-700">
                      {{ message }}
                  </p>
              </div>
            {% else%}
                <div class="rounded border-s-4 mb-1 border-red-500 bg-red-50 p-4">
                  <strong class="block font-medium text-red-800"> Something went wrong </strong>
                  <p class="mt-2 text-sm text-red-700">
                      {{ message }}
                  </p>
                </div>
            {% endif %}
        {% endfor %}
      {% endif %}

      <h1 class="text-center text-2xl font-bold text-black sm:text-3xl">Book Appointment</h1>
  
      <p class="mx-auto mt-4 max-w-md text-center text-gray-500">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati sunt
        dolores deleniti inventore quaerat mollitia?
      </p>
  
      <form method="post" action="" class="mb-0 mt-6 space-y-4 rounded-lg p-4 shadow-lg sm:p-6 lg:p-8">
        <p class="text-center text-lg font-medium">Appointment form</p>
        {% csrf_token %}
        <div>
            <label for="name" class="sr-only">Name</label>
  
          <div class="relative">
            <input type="text" name="name" class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm outline-blue-600" placeholder="Enter name">
          </div>
        </div>

        <div>
            <label for="email" class="sr-only">Email</label>
    
            <div class="relative">
              <input type="email" name="email" class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm outline-blue-600" placeholder="Enter email">
            </div>
        </div>
        
        <div>
            <label for="phonenumber" class="sr-only">Phone number</label>
    
            <div class="relative">
              <input type="tel" name="phone_number" class="w-full rounded-lg border-gray-200 p-4 pe-12 text-sm shadow-sm outline-blue-600" placeholder="Enter phone number" maxlength="10">
            </div>
        </div>
        <button type="submit" class="block w-full rounded-lg bg-black px-5 py-3 text-sm font-medium text-white">Book appointment</button>
    </form>
    </div>
  </div>
{% endblock %}

views.py代码

def create_appointment(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        email = request.POST.get('email')
        phone_number = request.POST.get('phone_number')
        date_str = request.session.get('date')
        time = request.session.get('time')

        date = datetime.fromisoformat(date_str)

        if Appointment.objects.filter(email=email).exists():
            messages.error(request, 'This email is already booked for an appointment.', extra_tags='error')
            return redirect('appointment')

        if Appointment.objects.filter(phone_number=phone_number).exists():
            messages.error(request, 'This Phone number is already booked for an appointment.', extra_tags='error')
            return redirect('appointment')

        booking = Appointment.objects.create(name=name, email=email, phone_number=phone_number, date=date, time=time, user=request.user)
        booking.save()

        subject = 'Appointment Confirmation'
        message = f'Thank you for the appointment \n\n Dear {booking.name},\n\nYour appointment for {booking.date.date()} at {booking.time} has been successfully booked.\n\nYour token number is: {booking.token} \n\nPhone Number: {booking.phone_number}\n\nIf you want to cancel the appointment, just call: 91XXXXXXXX \n\nThank you!'
        from_email = settings.EMAIL_HOST_USER 
        recipient_list = [booking.email]

        send_mail(subject, message, from_email, recipient_list, fail_silently=False)
        messages.success(request, 'Appointment created successfully.', extra_tags='success')
        del request.session['date']
        del request.session['time']
        return redirect('appointment')  

    return render(request, 'appointment.html' , {'time':'appointment' , 'title':'Appointment'})

问题原因

Django消息框架中,messages.error()默认自动添加error标签,messages.success()默认添加success标签。你通过extra_tags重复添加了同名标签,导致message.tags实际是空格分隔的重复字符串(比如成功消息的tags是success success,错误消息的tags是error error)。而HTML模板中用== 'success'精确匹配,无法匹配到实际的tags值,导致判断逻辑失效,最终样式颠倒。

修复方案

方案1:移除重复的extra_tags参数

修改views.py中的消息调用,去掉extra_tags,框架已自动添加对应标签:

# 错误消息修改为
messages.error(request, 'This email is already booked for an appointment.')
# ...
messages.error(request, 'This Phone number is already booked for an appointment.')

# 成功消息修改为
messages.success(request, 'Appointment created successfully.')

修改后message.tags会是success或error,HTML中的精确匹配即可正常生效。

方案2:修改HTML模板的判断逻辑

如果需要保留extra_tags,将模板中的精确匹配改为包含判断(message.tags是空格分隔的字符串):

{% if 'success' in message.tags %}
    <!-- 成功样式 -->
{% elif 'error' in message.tags %}
    <!-- 错误样式 -->
{% endif %}

这种方式更灵活,后续添加其他标签也能正常匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:55:53