Django多用户应用登录异常求助:登录表单触发用户名重复错误
问题分析与解决方案
问题根源
你的登录表单LoginForm继承了ModelForm,而ModelForm会自动应用模型的字段验证规则。由于CustomUser继承自AbstractUser,其中username字段默认带有唯一性约束(unique=True),当你提交登录表单时,ModelForm会错误地执行「检查用户名是否已存在」的验证——这是为创建新用户设计的逻辑,完全不符合登录场景的需求,因此会抛出A user with that user name already exists的错误。
修复步骤
1. 修改登录表单为普通Form
将forms.py中的LoginForm从ModelForm改为普通的forms.Form,只负责收集用户名和密码,不关联模型的创建验证:
from django import forms class LoginForm(forms.Form): username = forms.CharField(max_length=150) password = forms.CharField(widget=forms.PasswordInput())
2. 登录逻辑无需调整
你的LoginView中的验证逻辑是正确的,修改表单后,form.is_valid()只会验证字段格式是否合法(比如用户名非空、密码非空),不会再触发模型的唯一性验证,后续的authenticate和login流程可以正常执行。
额外优化建议(可选)
你的注册表单(如AdminSignUpForm)直接使用ModelForm保存密码会导致密码明文存储,需要重写save方法来加密密码:
以AdminSignUpForm为例:
class AdminSignUpForm(forms.ModelForm): account_type = forms.CharField(max_length=20, widget=forms.HiddenInput(), initial='admin') first_name = forms.CharField(max_length=30) last_name = forms.CharField(max_length=30) email = forms.EmailField() username = forms.CharField(max_length=150) password = forms.CharField(max_length=128, widget=forms.PasswordInput()) confirm_password = forms.CharField(max_length=128, widget=forms.PasswordInput()) class Meta: model = CustomUser fields = ['first_name', 'last_name', 'email', 'username', 'password', 'confirm_password'] def clean(self): cleaned_data = super().clean() password = cleaned_data.get('password') confirm_password = cleaned_data.get('confirm_password') if password != confirm_password: self.add_error('confirm_password', 'Passwords do not match') return cleaned_data def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data['password']) if commit: user.save() return user
其他注册表单也需要做同样修改,确保密码安全存储。
内容的提问来源于stack exchange,提问作者mdaw11
相关产品推荐
相关产品推荐

