Django用户登录异常:仅终端创建用户可登录,网站注册用户无法登录
问题分析与解决方案
你的核心问题是网站注册用户无法登录,但超级用户可以,结合代码来看,主要有两个关键问题需要修复:
1. 登录时authenticate参数错误
Django的authenticate函数默认使用username参数匹配用户模型的USERNAME_FIELD,而你的模型设置了USERNAME_FIELD = 'Email',所以应该用username=Email而非Email=Email作为参数。
修复代码:
views.py(登录逻辑):
把user = authenticate(Email=Email, password=password)改成:user = authenticate(username=Email, password=password)forms.py:
把if not authenticate(Email=Email, password=password):改成:if not authenticate(username=Email, password=password):
2. 注册时密码未正确哈希
通过createsuperuser创建用户时,Django会自动哈希密码,但你自定义的用户管理器如果没有正确实现create_user方法,注册用户的密码会以明文存储,导致authenticate验证失败。
修复步骤:
第一步:完善自定义用户管理器
在models.py中添加正确的CustomUserManager实现(如果还没写):
from django.contrib.auth.base_user import BaseUserManager class CustomUserManager(BaseUserManager): def create_user(self, Email, Username, FirstName, LastName, password=None, **extra_fields): if not Email: raise ValueError("必须提供邮箱地址") # 标准化邮箱格式(转小写) email = self.normalize_email(Email) user = self.model( Email=email, Username=Username, FirstName=FirstName, LastName=LastName, **extra_fields ) # 哈希密码 user.set_password(password) user.save(using=self._db) return user def create_superuser(self, Email, Username, FirstName, LastName, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) if extra_fields.get('is_staff') is not True: raise ValueError("超级用户必须设置is_staff=True") if extra_fields.get('is_superuser') is not True: raise ValueError("超级用户必须设置is_superuser=True") return self.create_user(Email, Username, FirstName, LastName, password, **extra_fields)
第二步:确保注册表单正确处理密码
如果你的UserRegistrationForm继承自UserCreationForm,需要适配自定义模型:
from django.contrib.auth.forms import UserCreationForm class UserRegistrationForm(UserCreationForm): class Meta: model = Trickster_User fields = ('Email', 'Username', 'FirstName', 'LastName')
UserCreationForm会自动处理密码确认和哈希,无需额外编写逻辑。
如果是自定义表单,必须在save方法中手动哈希密码:
class UserRegistrationForm(forms.ModelForm): password1 = forms.CharField(label='密码', widget=forms.PasswordInput(attrs={'class':'form-control'})) password2 = forms.CharField(label='确认密码', widget=forms.PasswordInput(attrs={'class':'form-control'})) class Meta: model = Trickster_User fields = ('Email', 'Username', 'FirstName', 'LastName') def clean_password2(self): password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError("两次输入的密码不一致") return password2 def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() return user
3. 模板拼写错误(可选但建议修复)
你的登录和注册模板中有拼写错误,会导致错误信息无法正确显示:
feild→fieldnon_feild_errors→non_field_errors- 错误循环中的
errors变量改为error,并显示{{ error }}而非{{ feild.errors }}
测试流程
- 删除之前注册的用户(他们的密码是明文存储,无法验证)
- 重启Django服务器
- 注册新用户,尝试登录,应该可以成功
内容的提问来源于stack exchange,提问作者Kona Hay
相关产品推荐
相关产品推荐

