Django自定义用户模型:后台创建用户无法登录管理站点
问题与解决:自定义Django用户模型后台创建用户密码未加密导致登录失败
问题描述
我通过AbstractUser创建了自定义Employee用户模型,并在settings中配置了AUTH_USER_MODEL = 'emp.Employee'。使用python manage.py createsuperuser创建的用户可正常登录管理后台,但直接在后台创建的用户(已勾选staff和superuser权限)无法登录,报错提示“请输入正确的员工账户邮箱和密码”。经检查,后台创建的用户密码未加密,这是导致登录失败的直接原因。
相关代码
models.py
class Department(models.Model): department_name = models.CharField(max_length=20) def __str__(self): return self.department_name class Role(models.Model): role_name = models.CharField(max_length=120) def __str__(self): return self.role_name class Task(models.Model): task_desp = models.TextField(max_length=100) in_progress = models.BooleanField() def __str__(self): return self.task_desp class Employee(AbstractUser): username = None email = models.EmailField(max_length=100,unique=True) phone_number = models.CharField(max_length=14) department = models.ForeignKey(Department,on_delete=models.CASCADE,null=True,blank=True) role = models.ForeignKey(Role,on_delete=models.CASCADE,null=True,blank=True) address = models.TextField(max_length=200) task_assigned = models.ForeignKey(Task,on_delete=models.CASCADE,null=True,blank=True) USERNAME_FIELD= 'email' REQUIRED_FIELDS = ['phone_number'] objects= UserManager() def __str__(self): return self.email
manager.py
from django.contrib.auth.base_user import BaseUserManager class UserManager(BaseUserManager): use_in_migrations = True def create_user(self,email,password=None,**extra_fields): if not email: raise ValueError("Please provide email") email = self.normalize_email(email) user = self.model(email=email,**extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self,email,password,**extra_fields): extra_fields.setdefault('is_staff',True) extra_fields.setdefault('is_superuser',True) extra_fields.setdefault('is_active',True) if extra_fields.get('is_staff') is not True: raise ValueError("super user must have staff user") return self.create_user(email,password,**extra_fields)
解决方法
问题出在默认的Django admin表单不会自动调用自定义UserManager中的set_password方法,导致后台创建用户时密码未加密。需要自定义admin表单和用户管理类,确保密码被正确加密。
在应用目录下创建admin.py,添加以下代码:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserCreationForm, UserChangeForm from .models import Employee class CustomUserCreationForm(UserCreationForm): class Meta: model = Employee fields = ('email', 'phone_number') class CustomUserChangeForm(UserChangeForm): class Meta: model = Employee fields = ('email', 'phone_number', 'department', 'role', 'address', 'task_assigned', 'is_staff', 'is_superuser') class EmployeeAdmin(UserAdmin): add_form = CustomUserCreationForm form = CustomUserChangeForm model = Employee list_display = ('email', 'phone_number', 'department', 'role', 'is_staff') fieldsets = ( (None, {'fields': ('email', 'password')}), ('Personal info', {'fields': ('phone_number', 'department', 'role', 'address', 'task_assigned')}), ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser')}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'phone_number', 'password1', 'password2', 'is_staff', 'is_superuser'), }), ) search_fields = ('email',) ordering = ('email',) admin.site.register(Employee, EmployeeAdmin)
说明
CustomUserCreationForm继承自UserCreationForm,该表单内部会自动调用set_password方法处理密码加密,确保后台创建用户时密码被正确哈希。EmployeeAdmin继承自UserAdmin,指定了自定义的添加和修改表单,同时配置了后台显示的字段和布局,让用户管理更贴合自定义模型的需求。
完成以上配置后,重启服务,再通过后台创建用户时,密码会被自动加密,用户即可正常登录管理后台。
内容的提问来源于stack exchange,提问作者user7477875
相关产品推荐
相关产品推荐

