必须在项目初期就替换User模型,因为Django auth系统首次迁移后会固化默认User表,后续修改AUTH_USER_MODEL将引发迁移冲突或数据丢失;需在首次migrate前定义自定义模型、配置AUTH_USER_MODEL、继承AbstractUser或AbstractBaseUser,并正确实现Manager、Admin适配及第三方包兼容。

为什么必须在项目初期就替换 User 模型?
不能等写完登录、权限逻辑再换——Django 的 auth 系统会在首次迁移时把默认 User 表固化到数据库里,之后再改 AUTH_USER_MODEL 会导致迁移冲突甚至数据丢失。
哪怕你只打算加个手机号字段,也得在 manage.py startproject 后、第一次运行 python manage.py migrate 前完成自定义模型定义和配置。
- 必须在
settings.py中提前设置AUTH_USER_MODEL = 'myapp.CustomUser'(注意格式:'app_name.ModelName',不是导入路径) - 自定义模型必须继承
AbstractBaseUser或AbstractUser;选前者意味着你要自己实现is_active、is_staff、is_superuser等字段和方法;选后者只需重写USERNAME_FIELD和REQUIRED_FIELDS - 如果已有迁移文件(比如 0001_initial.py),删掉它们再重新
makemigrations,否则会报RelatedField has invalid relation
用 AbstractUser 扩展比从头写 AbstractBaseUser 更稳妥
除非你明确要砍掉邮箱、密码重置、组权限等默认功能,否则直接继承 AbstractUser 能复用 Django 内置的 admin、login view、UserCreationForm 等全部逻辑,省去大量手动适配。
常见错误是只加字段却不重写 REQUIRED_FIELDS,导致 createsuperuser 命令仍要求输入 username 和 email,而你的模型可能已用 phone_number 当唯一标识。
立即学习“Python免费学习笔记(深入)”;
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 示例:以手机号登录时,设
USERNAME_FIELD = 'phone_number',并把username设为blank=True, null=True(Django 要求USERNAME_FIELD非空,但允许其他字段为空) -
REQUIRED_FIELDS列表里只放非空且非用户名的字段,比如['name'];email如果不强制,就别写进去 - 务必重写
CustomUserManager的create_user()和create_superuser(),确保新字段被正确赋值,否则createsuperuser会忽略你加的字段
Django Admin 中注册自定义用户必须用 UserAdmin 适配器
直接 admin.site.register(CustomUser) 会导致 admin 页面无法编辑密码、看不到权限字段、缺少用户组管理入口——因为默认 admin 对象是为原生 User 写的。
必须用 from django.contrib.auth.admin import UserAdmin 并继承它,否则连密码修改都会失败(admin 提交时调用的是 set_password(),但裸模型没暴露这个接口)。
- 在
admin.py中定义类时,需显式指定list_display、fieldsets、add_fieldsets,尤其是add_fieldsets要匹配你重写的REQUIRED_FIELDS,否则新建用户表单缺字段 -
fieldsets里要把password单独列在第一个区块,Django admin 依赖这个顺序触发密码哈希逻辑 - 如果加了
phone_number字段,记得在list_display和search_fields里加上,不然 admin 列表搜不到
第三方包如 django-allauth 或 django-rest-auth 需要额外适配
这些包默认硬编码引用 auth.User,不认你的 CustomUser。即使设置了 AUTH_USER_MODEL,它们仍可能在序列化、邮件模板、社交登录回调里抛 AttributeError。
比如 allauth 的邮箱验证模板里写死 {{ user.username }},而你的模型没有 username 字段,页面就会 500。
- 检查包文档是否声明支持自定义用户;不支持的包(如老版本
django-registration)建议换掉 - 覆盖模板时,把所有
{{ user.username }}改成{{ user.phone_number }}或对应字段 - REST 接口返回用户数据时,确保序列化器(如
UserSerializer)指向你的模型,而不是auth.User
最易被忽略的是信号(post_save)和中间件里对 User 的硬引用——全局搜索项目里所有 from django.contrib.auth.models import User,替换成 get_user_model()。

















