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
相关产品推荐
相关产品推荐

