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

DRF中密码无法哈希存储问题求助

DRF中Serializer的create方法无法实现密码哈希存储?

我用Django REST Framework开发时,定义了Customer模型和对应的CustomerSerializer,希望把用户密码以哈希形式存储。但尝试了三种重写Serializer的create方法的实现后,密码还是明文存在数据库里(Admin后台能看到)。不过重写save方法做密码哈希时功能正常,想知道是不是Serializer的create方法本来就没法实现这个功能?

模型代码

class CustomerStatus(models.TextChoices):
    ACTIVE = 'ACT', 'Active'
    EXPIRED = 'EXP', 'Expired'
    REVOKED = 'REV', 'Revoked'


class Customer(models.Model):
    email = models.EmailField(max_length=254, unique=True)
    password = models.CharField(max_length=128)
    created = models.DateTimeField(auto_now_add=True)
    status = models.CharField(
        max_length=3, choices=CustomerStatus.choices, default=CustomerStatus.ACTIVE
    )

Serializer代码

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['email', 'password', 'created', 'status']
        extra_kwargs = {'password': {'write_only': True}}

尝试过的三种create方法实现

def create(self, validated_data):
        validated_data['password'] = make_password(validated_data['password'])
        return super(CustomerSerializer, self).create(validated_data)
def create(self, validated_data):
        validated_data['password'] = make_password(validated_data['password'])
        return super().create(validated_data)
customer = Customer.objects.create(
            email=validated_data['email'],
            password=make_password(validated_data['password']),
        )

        return customer

问题解答

首先明确:Serializer的create方法完全可以实现密码哈希存储,你遇到的问题大概率是代码执行逻辑的问题,而非方法本身的限制。

可能的问题排查方向

  • 是否正确导入make_password:必须在Serializer文件顶部导入from django.contrib.auth.hashers import make_password,如果未导入,make_password会抛出异常,导致哈希逻辑未执行(可查看运行日志确认是否有报错)。
  • 是否有其他代码覆盖密码值:检查Customer模型是否重写了save方法,或是否有信号(Signal)在保存实例时重新设置了明文密码;同时确认视图层(如CreateAPIView)没有在调用Serializer后修改密码字段。
  • 确认数据库真实存储值:Admin后台的显示可能存在自定义逻辑干扰,建议直接查看数据库表的password字段,确认是否真的为明文。

你的三种实现的正确性

你的三种create写法本身都是逻辑正确的:

  • 写法1和2通过修改validated_data后调用父类create,父类会使用修改后的参数创建实例,密码应被正确哈希。
  • 写法3直接调用Customer.objects.create并传入哈希后的密码,逻辑上无任何问题。

重写save方法有效的原因

重写模型的save方法时,每次保存都会执行哈希逻辑,相当于在更底层处理密码,避免了上层代码(Serializer、视图)的干扰,但这并不代表Serializer的create方法无法实现该功能。

推荐的正确实现示例

确保导入make_password后,Serializer的create方法可按以下方式编写:

from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from .models import Customer

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['email', 'password', 'created', 'status']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        # 对密码进行哈希处理
        validated_data['password'] = make_password(validated_data['password'])
        # 调用父类方法创建实例
        return super().create(validated_data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:15:35