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

如何在Django模板中渲染ValidationError?密码验证报错不显示求助

解决Django注册表单密码不匹配错误不显示的问题

1. 修复视图逻辑错误

你当前的views.py存在逻辑漏洞:当POST请求且表单验证失败时,代码会重新创建空表单,导致错误信息全部丢失。修改如下:

def sign_up(request):
    if request.method == "POST":
        form = RegisterUserForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('pages:index')
        # 验证失败时保留带错误的表单,不重新创建
    else:
        form = RegisterUserForm()  # 仅GET请求时生成空表单
    return render(request=request, template_name="users/sign_up.html", context={'form': form})

2. 完善表单的密码验证逻辑

当前表单的clean方法存在两个问题:未处理字段为空的情况、未正确导入ValidationError。优化后代码如下:

from django import forms
from .models import CustomUser
from django.core.exceptions import ValidationError  # 必须导入该类

class RegisterUserForm(forms.ModelForm):
    email = forms.EmailField(required=True,
                            label="Адрес электронной почты",
                            widget=forms.EmailInput(attrs={'class': 'form-control',
                                                        'placeholder':'email'}))
    password = forms.CharField(label='Пароль',
                            widget=forms.PasswordInput(attrs={'class': 'form-control',
                                                            'placeholder':'password'}))
    confirm_password = forms.CharField(label='Пароль(повторно)',
                            widget=forms.PasswordInput(attrs={'class': 'form-control',
                                                            'placeholder':'confirm password'}))

    def clean(self):
        cleaned_data = super().clean()  # 接收父类处理后的cleaned_data
        password = cleaned_data.get('password')  # 用get避免字段为空时抛出KeyError
        confirm_password = cleaned_data.get('confirm_password')
        
        # 仅当两个字段都有值时才验证一致性
        if password and confirm_password and password != confirm_password:
            self.add_error('confirm_password', 'пароли не совпадают')  # 给指定字段绑定错误
        return cleaned_data  # 必须返回处理后的cleaned_data

    class Meta:
        model = CustomUser
        fields = ("email", "password", "confirm_password")

    # 额外:添加密码哈希逻辑,避免明文存储密码
    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user

3. 优化模板的错误显示位置

当前模板仅在末尾显示全局错误,建议将字段错误放在对应字段下方,提升用户体验,同时修正<head>标签的顺序错误:

<head>
    <link rel="stylesheet" type="text/css" href="{% static 'users/css/style.css' %}">
</head>

<div class="text-center log-in-bg rounded">
    <img class="mb-4" src="{% static "users/images/logo_sign_in.png" %}" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal text-dark">РЕГИСТРАЦИЯ</h1>
    <form method="post" class="form-signin">
        {% csrf_token %}
        
        {{ form.email.label_tag }}
        {{ form.email }}
        {% if form.email.errors %}
            <div class="text-danger">{{ form.email.errors }}</div>
        {% endif %}
        
        {{ form.password.label_tag }}
        {{ form.password }}
        {% if form.password.errors %}
            <div class="text-danger">{{ form.password.errors }}</div>
        {% endif %}
        
        {{ form.confirm_password.label_tag }}
        {{ form.confirm_password }}
        {% if form.confirm_password.errors %}
            <div class="text-danger">{{ form.confirm_password.errors }}</div>
        {% endif %}

        <!-- 显示全局非字段错误 -->
        {% if form.non_field_errors %}
            <div class="text-danger">{{ form.non_field_errors }}</div>
        {% endif %}

        <button class="btn btn-lg btn-sign-in btn-block">Зарегистрироваться</button>
    </form>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:21:34