核心目标:掌握使用 AbstractUser
或 AbstractBaseUser
创建自定义用户模型的方法,并正确进行项目配置与数据库迁移。
一、为什么需要自定义用户模型?
- 局限性:内置
User
模型无法满足更多需求- 需要额外字段(如手机号、头像、用户类型)
- 需要改变默认登录凭证(如用邮箱代替用户名)
- 最佳实践:项目开始前就创建自定义用户模型
二、AbstractUser
与 AbstractBaseUser
的区别
特性 | AbstractUser | AbstractBaseUser |
---|---|---|
基础字段 | 包含完整字段(username, email) | 仅包含核心字段(密码、最后登录时间) |
适用场景 | 小幅度扩展 (增加字段) | 完全自主设计用户模型 (如去掉用户名字段) |
灵活性 | 低 (默认使用用户名认证) | 高 (需自行实现认证管理器) |
开发成本 | 低 | 高 |
三、AbstractUser
快速上手
1. 创建模型
# users/models.py
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
# 添加自定义字段
mobile = models.CharField('手机号', max_length=11, unique=True)
avatar = models.ImageField('头像', upload_to='avatars/', blank=True)
# 可覆盖默认字段 (如改用邮箱作为用户名)
USERNAME_FIELD = 'email' # 定义唯一标识字段
EMAIL_FIELD = 'email' # Django内置邮件相关功能依赖此字段
REQUIRED_FIELDS = ['username'] # 使用createsuperuser时的必填字段
def __str__(self):
return self.email
2. 配置生效
# settings.py
AUTH_USER_MODEL = 'users.CustomUser' # 格式:应用名.模型名
四、AbstractBaseUser
完全自定义
1. 创建模型与认证管理器
# users/models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('必须填写邮箱')
user = self.model(email=self.normalize_email(email), **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser):
email = models.EmailField('邮箱', unique=True)
name = models.CharField('姓名', max_length=50)
is_active = models.BooleanField('激活状态', default=True)
is_staff = models.BooleanField('后台权限', default=False)
USERNAME_FIELD = 'email' # 登录标识字段
REQUIRED_FIELDS = ['name'] # 创建超级用户时的必填字段
objects = MyUserManager() # 绑定自定义管理器
2. 必须配置项
# settings.py
AUTH_USER_MODEL = 'users.CustomUser'
五、迁移策略
1. 首次创建用户模型
-
创建
users
应用python manage.py startapp users
-
创建模型后执行迁移
python manage.py makemigrations python manage.py migrate
2. 已存在数据的项目
-
开发环境:
# 删除数据库 (db.sqlite3) # 删除所有应用的迁移文件 (migrations/000*.py) # 重新生成迁移文件并执行 python manage.py makemigrations python manage.py migrate
-
生产环境:
使用数据迁移工具,或参考 官方文档进行 复杂迁移
六、关联模型引用方式
正确做法:使用 settings.AUTH_USER_MODEL
(避免直接导入 User
)
# posts/models.py
from django.conf import settings
from django.db import models
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL, # 🔑 使用配置的用户模型
on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
七、常见错误解决
- 错误:
django.db.migrations.exceptions.InconsistentMigrationHistory
原因:已执行过内置 User 模型的迁移后更换用户模型
解决方案:按照迁移策略清理数据库和迁移文件后重新迁移 - 错误:
AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.CustomUser'
原因:代码中硬编码引用了User
模型
修复:所有引用用户的位置改用settings.AUTH_USER_MODEL
总结
场景 | 选择 |
---|---|
需添加少量字段 | 继承 AbstractUser |
需完全自定义用户模型(如邮箱登录) | 继承 AbstractBaseUser |
关键步骤:
- 根据需求选择合适的基类
- 配置
AUTH_USER_MODEL
- 处理数据库迁移
- 所有外键使用
settings.AUTH_USER_MODEL
通过自定义用户模型,可构建更贴合业务需求的认证系统。下一步建议尝试集成手机号登录或第三方登录功能。
下一步计划
- 利用自定义模型实现邮箱+密码登录
- 结合 Django Signals 实现用户创建后的欢迎邮件发送