You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义用户模型中create_password字段无法哈希问题求助

如何在自定义AbstractBaseUser模型中对自定义密码字段进行哈希处理

问题核心在于Django的AbstractBaseUser类默认是基于password字段实现密码哈希逻辑的,包括set_password()和check_password()方法都是针对这个字段设计的。当你把字段名改成create_password后,默认的哈希机制就不再生效了——哪怕你调用set_password(),它依然会把哈希值存入原本的password字段(而你现在的模型里可能已经没有这个字段,或者没用到它)。

下面提供两种可行的解决方案:

方案一:重写密码处理方法适配自定义字段

如果你坚持要用create_password作为存储哈希密码的字段,需要在自定义User模型中重写set_password()和check_password()方法,让它们指向你的新字段:

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
from django.contrib.auth.hashers import make_password, check_password

class CustomUserManager(BaseUserManager):
    def create_user(self, email, raw_password, **extra_fields):
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(raw_password)  # 调用重写后的方法
        user.save(using=self._db)
        return user

class CustomUser(AbstractBaseUser):
    email = models.EmailField(unique=True)
    create_password = models.CharField(max_length=150)
    # 其他自定义字段...

    objects = CustomUserManager()
    USERNAME_FIELD = 'email'

    def set_password(self, raw_password):
        # 生成密码哈希并赋值给create_password
        self.create_password = make_password(raw_password)
        self._password = raw_password  # 跟踪密码修改状态,兼容Django内部逻辑

    def check_password(self, raw_password):
        # 验证原始密码与create_password中的哈希是否匹配
        return check_password(raw_password, self.create_password)

方案二:保留默认password字段,用自定义字段接收输入(推荐)

这种方式更贴合Django的原生设计,避免重写核心方法:

  1. 你的自定义User模型继承AbstractBaseUser后,默认已经包含password字段(无需自己定义),只需添加create_password作为临时接收原始密码的字段:
class CustomUser(AbstractBaseUser):
    email = models.EmailField(unique=True)
    create_password = models.CharField(max_length=150, blank=True, null=True)
    # 其他自定义字段...

    objects = CustomUserManager()
    USERNAME_FIELD = 'email'
  1. 在创建/更新用户时,用create_password的原始值调用set_password(),将哈希存入默认的password字段,之后清空明文密码:
# 创建用户示例
user = CustomUser(email='user@example.com', create_password='raw_password123')
user.set_password(user.create_password)  # 生成哈希存入password字段
user.create_password = None  # 清空明文,避免存储
user.save()

注意事项

  • 不要直接给create_password赋值明文密码后保存,必须通过set_password()方法处理哈希。
  • 如果你之前覆盖了AbstractBaseUser的password字段,建议删除自定义的password定义,直接使用父类自带的字段,避免冲突。

内容的提问来源于stack exchange,提问作者harshit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:56:07