Django自定义用户模型set_password未哈希密码问题求助
问题分析与解决方案
核心错误:自定义管理器属性名拼写错误
你的CustomUser模型中,自定义管理器的属性名写成了object,而Django模型默认的管理器属性名必须是objects。这个错误会导致Django在大多数场景(比如admin后台创建用户、直接调用CustomUser.objects.create_user)下使用父类的默认管理器,而非你自定义的CustomUserManager,从而跳过了_create_user方法中的user.set_password(password)哈希逻辑。只有createsuperuser命令因特殊查找逻辑调用了自定义方法,所以超级用户密码能正常哈希。
修复步骤:
修改models.py中的CustomUser类,把object改为objects:
class CustomUser(AbstractUser): email = models.EmailField(_("email address"), null=False, blank=False, unique=True) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ["username"] objects = CustomUserManager() # 修正属性名为objects
无需使用make_password
你不需要手动调用make_password,因为Django提供的set_password()方法已经内部封装了密码哈希逻辑(底层就是调用make_password),使用set_password()更符合Django认证体系规范,还能自动处理密码加盐等安全细节。
完善Admin后台配置
即使修复了管理器名称,默认的Django Admin表单在创建/编辑用户时,可能不会自动调用自定义管理器的create_user方法,仍可能出现密码未哈希的情况。需要自定义UserAdmin类确保密码正确处理:
修改admin.py:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth import get_user_model from django.contrib.auth.forms import UserCreationForm, UserChangeForm # 自定义用户创建表单 class CustomUserCreationForm(UserCreationForm): class Meta: model = get_user_model() fields = ('email', 'username') # 自定义用户编辑表单 class CustomUserChangeForm(UserChangeForm): class Meta: model = get_user_model() fields = ('email', 'username', 'is_active', 'is_staff') # 自定义UserAdmin类 class CustomUserAdmin(UserAdmin): add_form = CustomUserCreationForm form = CustomUserChangeForm model = get_user_model() # 列表页显示字段 list_display = ('email', 'username', 'is_staff', 'is_active') # 详情页字段分组 fieldsets = ( (None, {'fields': ('email', 'password')}), ('个人信息', {'fields': ('username',)}), ('权限设置', {'fields': ('is_active', 'is_staff', 'is_superuser')}), ('重要日期', {'fields': ('last_login', 'date_joined')}), ) # 添加用户时的字段分组 add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'username', 'password1', 'password2', 'is_staff', 'is_active')} ), ) search_fields = ('email', 'username') ordering = ('email',) # 重写save_model确保密码哈希 def save_model(self, request, obj, form, change): # 新创建用户时处理密码 if not change: obj.set_password(form.cleaned_data['password1']) # 编辑用户时如果修改了密码,重新哈希 elif 'password' in form.changed_data and form.cleaned_data['password']: obj.set_password(form.cleaned_data['password']) super().save_model(request, obj, form, change) # 注册自定义用户模型和UserAdmin admin.site.register(get_user_model(), CustomUserAdmin)
验证修复效果
- 运行数据库迁移(如果有必要):
python manage.py makemigrations python manage.py migrate
- 尝试在Admin后台创建新用户,检查数据库中密码字段是否为哈希值(而非明文)。
- 在代码中使用
CustomUser.objects.create_user()创建用户,验证密码是否正常哈希。
内容的提问来源于stack exchange,提问作者Abdullah Moudood
相关产品推荐
相关产品推荐

