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

为何Django允许两个不同密码提交且无报错?

排查Django自定义用户注册时密码确认不校验的问题

这种情况我碰到过好几次,大概率是表单校验逻辑缺失或者视图没有触发校验流程导致的。咱们一步步来排查:

1. 先检查你的forms.py:密码确认的校验逻辑有没有加?

Django的ModelForm默认不会帮你做密码确认的校验,你得自己加字段和校验逻辑。如果你的表单是继承自UserCreationForm,它自带password1和password2的校验,但如果你是自定义的表单,或者没正确继承,就会出问题。

错误示例(缺少校验):

from django.forms import ModelForm
from .models import CustomUser

class RegisterForm(ModelForm):
    confirm_password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'password']

这个表单只加了confirm_password字段,但没有对比两个密码的逻辑,所以即使不一致也能提交。

正确做法:重写clean()方法或者用内置的校验

方法一:重写clean()做密码对比

from django import forms
from django.forms import ModelForm
from .models import CustomUser

class RegisterForm(ModelForm):
    confirm_password = forms.CharField(widget=forms.PasswordInput(), label="Confirm Password")

    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'password']
        widgets = {
            'password': forms.PasswordInput(),
        }

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        confirm_pwd = cleaned_data.get("confirm_password")

        # 校验两个密码是否一致
        if password and confirm_pwd and password != confirm_pwd:
            raise forms.ValidationError("Passwords don't match!")
        
        # 还要确保密码符合Django的复杂度要求(可选但推荐)
        if password:
            from django.contrib.auth.password_validation import validate_password
            try:
                validate_password(password)
            except forms.ValidationError as e:
                self.add_error('password', e)
        
        return cleaned_data

方法二:直接继承UserCreationForm(更省心)

如果你的自定义用户模型符合Django的用户规范,直接继承UserCreationForm它会自动帮你处理password1和password2的校验:

from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser

class CustomUserRegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'password1', 'password2']

这个表单自带密码一致性校验和复杂度校验,省得自己写。

2. 检查你的views.py:有没有触发表单校验?

就算表单写了校验逻辑,如果视图里没调用form.is_valid(),那校验根本不会执行!

错误示例(跳过校验):

def register(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        # 直接保存,没做校验
        user = form.save(commit=False)
        user.set_password(form.cleaned_data['password'])
        user.save()
        return redirect('login')
    else:
        form = RegisterForm()
    return render(request, 'register.html', {'form': form})

正确做法:必须先调用form.is_valid()

def register(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():  # 这一步会触发所有表单校验
            user = form.save(commit=False)
            # 注意:如果用了ModelForm,要确保密码是加密存储的
            user.set_password(form.cleaned_data['password'])
            user.save()
            return redirect('login')
    else:
        form = RegisterForm()
    return render(request, 'register.html', {'form': form})

form.is_valid()会自动调用你在表单里写的clean()方法,校验不通过的话会把错误信息放到form.errors里,模板里就能显示出来。

3. 额外检查:模板里的表单是否正确渲染?

确保模板里的confirm_password字段(或者password2)的name属性和表单里的字段名一致,不然表单接收不到这个值,校验也等于白写。比如:

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Register</button>
</form>

如果是手动写的输入框,要保证name="confirm_password"(和表单字段名一致):

<input type="password" name="confirm_password" required>

4. 最后检查managers.py:有没有越俎代庖?

一般来说,自定义用户管理器的create_user方法只负责创建用户、加密密码,不负责校验密码确认。比如正确的管理器应该是这样的:

from django.contrib.auth.base_user import BaseUserManager

class CustomUserManager(BaseUserManager):
    def create_user(self, email, username, password=None, **extra_fields):
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, username=username, **extra_fields)
        user.set_password(password)  # 这里只负责加密,不校验确认密码
        user.save(using=self._db)
        return user

如果你的管理器里没有做多余的操作,那问题肯定不在这。

按照上面的步骤排查,基本就能解决密码不校验的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:07:50