Django自定义用户模型Admin密码设置问题及角色模型设计咨询
一、Admin后台密码字段异常修复
问题原因
你注册User模型时直接继承了默认的admin.ModelAdmin,没有复用Django Auth模块自带的UserAdmin的密码处理逻辑,默认的ModelAdmin会将密码字段识别为普通文本字段,不会自动做加密存储处理,也不会渲染为密码输入框。
修复方案
修改admin.py代码如下:
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from .models import User, Customer, Employee, Responsable, Driver @admin.register(User) class UserAdmin(BaseUserAdmin): list_display = ('email', 'first_name', 'last_name', 'is_active', 'is_staff', 'created_at') # 编辑页字段分组 fieldsets = ( (None, {'fields': ('email', 'password')}), ('个人信息', {'fields': ('first_name', 'last_name', 'mobile')}), ('权限配置', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), ('角色标记', {'fields': ('is_customer', 'is_responsable', 'is_driver')}), ('时间信息', {'fields': ('created_at', 'updated_at')}), ) # 新增用户页字段分组,包含密码二次确认逻辑 add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'first_name', 'last_name', 'password1', 'password2'), }), ) search_fields = ('email', 'first_name', 'last_name') ordering = ('email',) readonly_fields = ('created_at', 'updated_at') # 客户模型Admin配置 class CustomerAdmin(BaseUserAdmin): fieldsets = UserAdmin.fieldsets + ( ('客户专属信息', {'fields': ('company_name', 'website', 'mobile_2')}), ) add_fieldsets = UserAdmin.add_fieldsets + ( ('客户专属信息', {'fields': ('company_name', 'website', 'mobile_2')}), ) # 员工模型Admin配置 class EmployeeAdmin(BaseUserAdmin): fieldsets = UserAdmin.fieldsets + ( ('员工专属信息', {'fields': ('registration_number', 'picture', 'birth_date', 'city_id', 'bank_id')}), ) add_fieldsets = UserAdmin.add_fieldsets + ( ('员工专属信息', {'fields': ('registration_number', 'picture', 'birth_date', 'city_id', 'bank_id')}), ) # 行政人员模型Admin配置 class ResponsableAdmin(EmployeeAdmin): fieldsets = EmployeeAdmin.fieldsets + ( ('行政专属信息', {'fields': ('responsability_type',)}), ) add_fieldsets = EmployeeAdmin.add_fieldsets + ( ('行政专属信息', {'fields': ('responsability_type',)}), ) # 司机模型Admin配置 class DriverAdmin(EmployeeAdmin): fieldsets = EmployeeAdmin.fieldsets + ( ('司机专属信息', {'fields': ('driving_licence', 'driver_licence_expiration_date')}), ) add_fieldsets = EmployeeAdmin.add_fieldsets + ( ('司机专属信息', {'fields': ('driving_licence', 'driver_licence_expiration_date')}), ) # 注册所有模型 admin.site.register(Customer, CustomerAdmin) admin.site.register(Employee, EmployeeAdmin) admin.site.register(Responsable, ResponsableAdmin) admin.site.register(Driver, DriverAdmin)
二、多角色模型设计说明
密码重复存储问题说明
你当前使用的是Django多表继承机制,所有继承自User的子类仅会在自身表中存储新增的角色专属字段,以及一个指向父表User的一对一外键,密码、基础账号信息仅会存储在最顶层的User表中,不会出现多表重复存储密码的情况,不需要担心这个问题。
设计优化建议
当前设计的局限性在于:一个用户只能对应一个角色,如果你的业务存在同一用户需要同时拥有多个角色的场景(比如某行政人员同时也是公司客户),可以改为使用OneToOne关联模式:将Employee、Customer、Responsable、Driver改为普通模型,不继承User,每个模型新增一个OneToOneField关联到User即可,灵活度更高。
如果业务中一个用户只会有一个固定角色,当前的多表继承设计完全可用,无需额外改动。
内容的提问来源于stack exchange,提问作者E.Mohammed
相关产品推荐
相关产品推荐

