Django自定义用户模型密码未哈希,非超级用户无法登录求助
问题分析与解决方案
核心问题
- ModelForm直接保存明文密码:你的
StudentRegistrationForm和TeacherRegistrationForm继承自ModelForm,直接调用form.save()时,会把表单中的明文password直接存入数据库,没有调用set_password()进行哈希处理。 - 代理模型的
create_user未被触发:ModelForm默认使用模型的objects.create()方法创建实例,不会调用你自定义管理器中的create_user(该方法包含密码哈希逻辑)。 - Admin后台未适配自定义用户模型:默认的Django Admin不会自动处理自定义用户模型的密码哈希,也无法正确创建普通用户。
- 权限方法限制过严:
has_perm方法直接返回self.is_admin,导致普通用户(非admin)没有任何权限,间接影响登录后的操作,核心登录失败原因还是密码未哈希。
解决方案
1. 修改表单,手动处理密码哈希
修改forms.py,重写save()方法,显式调用用户模型的set_password():
from django import forms from .models import Student, Teacher class StudentRegistrationForm(forms.ModelForm): # 显式定义密码字段,使用密码输入组件 password = forms.CharField(widget=forms.PasswordInput) class Meta: model = Student fields = ['email', 'password'] def save(self, commit=True): user = super().save(commit=False) # 对密码进行哈希处理 user.set_password(self.cleaned_data["password"]) if commit: user.save() return user class TeacherRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput) class Meta: model = Teacher fields = ['email', 'password'] def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password"]) if commit: user.save() return user
2. 修复自定义用户模型的权限方法
has_perm方法当前只允许admin用户拥有权限,修改为更合理的逻辑:
# 在UserAccount模型中修改 def has_perm(self, perm, obj=None): # 普通用户默认拥有基本权限,可根据业务需求调整 return self.is_active def has_module_perms(self, app_label): return self.is_active
3. 适配Django Admin后台
创建admin.py,自定义UserAdmin来处理密码哈希和用户创建:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import UserAccount, Student, Teacher class CustomUserAdmin(UserAdmin): # 自定义列表显示字段 list_display = ('email', 'type', 'is_active', 'is_staff') # 自定义编辑页面字段分组 fieldsets = ( (None, {'fields': ('email', 'password')}), ('权限设置', {'fields': ('is_active', 'is_staff', 'is_superuser', 'is_student', 'is_teacher')}), ('用户类型', {'fields': ('type',)}), ) # 自定义添加用户页面字段 add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'password1', 'password2', 'type', 'is_active', 'is_staff'), }), ) ordering = ('email',) filter_horizontal = () # 注册模型与自定义Admin admin.site.register(UserAccount, CustomUserAdmin) admin.site.register(Student) admin.site.register(Teacher)
4. 验证代理模型保存逻辑
当前代理模型的save方法已正确设置用户类型,无需修改:
- Student模型自动设置
type = STUDENT和is_student = True - Teacher模型自动设置
type = TEACHER和is_teacher = True
测试步骤
- 删除数据库中已存在的明文密码用户记录
- 执行迁移:
python manage.py migrate - 通过表单注册学生/教师,检查数据库中
password字段是否为哈希值(以pbkdf2_sha256$开头) - 使用注册用户登录,确认登录功能正常
- 在Admin后台创建用户,使用密码双输入框,确认密码被正确哈希
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

