Django登录表单form.is_valid()返回未定义DNI重复错误
Django登录表单is_valid()返回False排查方案
核心问题定位
你看到的“Intercambiador with this Dni already exists”错误,本质是登录表单意外引入了注册场景的DNI唯一性校验规则——登录只需要验证凭证合法性,不需要检查DNI是否已存在,这个逻辑属于注册表单。
具体排查步骤
- 检查表单继承关系:如果登录表单用了
ModelForm并关联Intercambiador模型,而模型的dni字段设了unique=True,ModelForm会自动生成唯一性校验,这就是错误来源。登录表单应该用普通Form类,而非ModelForm。 - 查看字段校验器:确认是否手动给
dni字段加了UniqueValidator,比如:
登录场景必须删除这个校验器。dni = forms.CharField(validators=[UniqueValidator(queryset=Intercambiador.objects.all())]) - 检查
clean_dni方法:有没有在字段级clean方法里写了DNI重复的校验逻辑,登录时应该判断DNI是否存在,而非不存在。 - 排查父类表单:如果登录表单继承了自定义基类表单,检查基类是否包含注册相关的校验逻辑。
修复示例
正确的登录表单应只做凭证合法性校验:
from django import forms from django.contrib.auth import authenticate from .models import Intercambiador class IntercambiadorLoginForm(forms.Form): dni = forms.CharField(label="DNI") password = forms.CharField(label="密码", widget=forms.PasswordInput) def clean(self): cleaned_data = super().clean() dni = cleaned_data.get('dni') password = cleaned_data.get('password') if dni and password: user = authenticate(request=self.request, username=dni, password=password) if not user: raise forms.ValidationError("DNI或密码错误") if not user.is_active: raise forms.ValidationError("账号已被封禁") return cleaned_data
内容的提问来源于stack exchange,提问作者Damián Bicocchi
相关产品推荐
相关产品推荐

