如何重写Django User模型并替换字段名且保留默认认证权限?
重写Django User模型并替换字段名(保留默认认证与权限)
完全可以通过自定义User模型实现你的需求,全程保留Django默认的认证机制和权限体系,以下是具体步骤:
1. 创建自定义用户管理器(UserManager)
先定义用户管理器,适配新字段名的用户创建逻辑:
from django.contrib.auth.models import BaseUserManager from django.db import models class CustomUserManager(BaseUserManager): def create_user(self, sr_usuario, sr_password=None, **extra_fields): if not sr_usuario: raise ValueError('必须设置sr_usuario字段') user = self.model(sr_usuario=sr_usuario, **extra_fields) user.set_password(sr_password) user.save(using=self._db) return user def create_superuser(self, sr_usuario, sr_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(sr_usuario, sr_password, **extra_fields)
2. 定义自定义User模型
继承AbstractBaseUser(处理认证核心逻辑)和PermissionsMixin(保留权限体系),替换字段名并适配密码处理:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from django.contrib.auth.hashers import make_password, check_password from django.db import models class CustomUser(AbstractBaseUser, PermissionsMixin): # 替换原username为sr_usuario,设置唯一约束 sr_usuario = models.CharField(max_length=150, unique=True) # 替换原password为sr_password sr_password = models.CharField(max_length=128) # 保留Django默认的状态字段 is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) # 绑定自定义用户管理器 objects = CustomUserManager() # 指定Django认证使用的唯一标识字段 USERNAME_FIELD = 'sr_usuario' REQUIRED_FIELDS = [] # 重写密码设置方法,适配sr_password字段 def set_password(self, raw_password): self.sr_password = make_password(raw_password) self._password = raw_password # 重写密码校验方法,适配sr_password字段 def check_password(self, raw_password): return check_password(raw_password, self.sr_password) # 兼容Django内部对password属性的访问 @property def password(self): return self.sr_password @password.setter def password(self, value): self.set_password(value) def __str__(self): return self.sr_usuario
3. 配置项目settings.py
在项目配置文件中指定自定义User模型为默认认证模型:
# settings.py AUTH_USER_MODEL = '你的应用名.CustomUser'
注意替换你的应用名为实际包含CustomUser模型的应用名称。
4. 适配Django Admin后台
为了在Admin后台正常管理自定义用户,需要注册自定义UserAdmin:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser class CustomUserAdmin(UserAdmin): # 调整后台显示的字段组 fieldsets = ( (None, {'fields': ('sr_usuario', 'sr_password')}), ('权限设置', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), ('重要日期', {'fields': ('last_login', 'date_joined')}), ) # 调整添加用户时的字段 add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('sr_usuario', 'sr_password1', 'sr_password2'), }), ) # 列表页显示字段 list_display = ('sr_usuario', 'is_staff') search_fields = ('sr_usuario',) ordering = ('sr_usuario',) admin.site.register(CustomUser, CustomUserAdmin)
5. 数据库迁移与测试
- 运行迁移命令,创建新的用户表:
python manage.py makemigrations python manage.py migrate
- 创建超级用户(使用sr_usuario作为用户名):
python manage.py createsuperuser
- 测试查询功能,此时可以正常使用:
# 示例查询 CustomUser.objects.filter(sr_usuario="user_name")
- 测试认证逻辑,视图中可以直接使用Django的
authenticate和login方法:
from django.contrib.auth import authenticate, login def login_view(request): if request.method == 'POST': sr_usuario = request.POST.get('sr_usuario') sr_password = request.POST.get('sr_password') # authenticate的username参数对应USERNAME_FIELD(即sr_usuario) user = authenticate(request, username=sr_usuario, password=sr_password) if user: login(request, user) # 登录成功跳转 else: # 登录失败处理
注意事项
- 如果是已有项目,需要谨慎处理数据迁移,避免丢失原有用户数据
- 所有涉及用户模型的地方(如外键、反向查询)都需要使用
settings.AUTH_USER_MODEL来引用,而非直接使用django.contrib.auth.models.User
内容的提问来源于stack exchange,提问作者Rafael Noronha
相关产品推荐
相关产品推荐

