跳转到主内容
极星编程网:以代码为星,赴技术山海!

Django怎么做注册_User模型扩展与密码make_password加密

最稳妥的用户模型扩展方式是用 OneToOneField 关联,而非继承 User;密码应通过 create_user 或 set_password 自动生成,禁止手动调用 make_password;扩展字段需在表单中显式声明并重写 save 方法。 为什么不能直接继承
User
模型做注册扩展 因为 Django 的
User
模型是抽象基类(
AbstractBaseUser
)的封装,硬继承会导致迁移冲突、admin 不兼容、认证逻辑断裂。最稳妥的方式是用
OneToOneField
关联,或从头自定义
AbstractBaseUser
—— 但后者要重写登录、管理命令、admin 注册等一堆东西,90% 的项目没必要。 实操建议: 用
OneToOneField
扩展:适合只需要加几个字段(如昵称、头像、手机号)的场景,兼容所有内置认证流程 用
AbstractBaseUser
+
PermissionsMixin
:仅当你需要改邮箱登录、禁用用户名、或彻底重构用户标识逻辑时才选 别碰
AbstractUser
继承:它和默认
User
表结构高度耦合,迁移后容易爆
django.db.utils.ProgrammingError: relation "auth_user" already exists
make_password
不该在视图里手动调用 Django 的
create_user
和
create_superuser
方法内部已经自动调用
make_password
,手动再套一层会导致密码被双重哈希,登录永远失败。典型错误现象是:注册成功,但
authenticate(username=..., password=...)
返回
None
,后台查
User.password
字段会发现值以
pbkdf2_sha256$
开头两次。 正确做法: 注册逻辑中,统一走
User.objects.create_user(username=..., email=..., password=...)
如果用了自定义用户模型,确保你的
create_user
方法里调用了
user.set_password(password)
(不是
make_password
),再
user.save()
绝对不要在表单
save()
或视图里写
user.password = make_password(raw)
—— 这等于绕过 Django 密码策略(比如 salt 长度、迭代次数) 扩展字段怎么进注册表单又不破坏
UserCreationForm
UserCreationForm
默认只管
username
、
password1
、
password2
。想加
email
或
phone
,不能靠覆盖
Meta.fields
简单追加,否则
clean()
和保存逻辑会漏掉新字段。 Python 网站开发之Django环境搭建 WORD版 本文档主要讲述的是Python 网站开发之Django环境搭建;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 实操要点: 继承
UserCreationForm
,在
Meta.model
指向你的扩展模型(如
CustomUserProfile
)前,先确认该模型是否已通过
OneToOneField
关联
User
把扩展字段声明在表单类体里(非
Meta
),例如:
email = forms.EmailField(required=True)
重写
save()
方法:先调
super().save()
得到
User
实例,再用它创建关联的扩展模型实例(注意传
user=user
) 如果扩展字段存在唯一性约束(如
phone
),必须在表单
clean()
里查库校验,不能只靠模型层
unique=True
—— 因为
User
和扩展模型是两张表 密码加密强度由
PASSWORD_HASHERS
决定,不是
make_password
参数 有人以为调
make_password(raw, salt, 'pbkdf2_sha256')
能指定算法,其实 Django 80% 的密码哈希行为由
settings.PASSWORD_HASHERS
控制。手动传算法名不仅多余,还可能降级安全强度(比如误用
md5
)。 关键事实:
make_password
的第三个参数是“强制使用某 hasher”,仅用于测试或迁移旧密码,生产环境不该出现 当前 Django 默认用
PBKDF2PasswordHasher
,迭代次数由
PASSWORD_HASHERS
中 hasher 类的
iterations
属性控制(默认 360000+) 改密钥轮数?别动
make_password
,去重写 hasher 类或调整
settings.PASSWORD_HASHERS
里的配置项 验证密码永远用
check_password(raw, hashed)
,它自动识别 hasher 类型,不需要你解析
hashed
字符串前缀 最容易被忽略的是:自定义用户模型的
set_password
方法是否真的调用了
BaseUserManager.make_random_password
或
hashers.make_password
—— 有些手写的
create_user
忘了这一行,导致明文存库。

相关文章