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

使用Django ModelViewSet时PUT/PATCH方法密码未加密的问题

问题原因与解决方法

原因分析

你的PUT/PATCH请求密码明文存储的核心问题在于update方法的实现:

  • 当调用super().update(instance, validated_data)时,DRF的ModelSerializer会直接将validated_data中的password明文赋值给用户实例的password字段,完全跳过了加密逻辑。
  • 同时,password2是自定义的确认字段,User模型并不存在该字段,如果不提前移除,父类的update方法会抛出字段不存在的异常。

你之前尝试的make_password()或set_password(make_password())无效,大概率是因为没有从validated_data中移除原始的明文password字段,导致父类的update操作覆盖了你手动加密后的密码值。

解决方法

修改update方法,提前处理密码加密逻辑,并移除不需要的password2字段,再调用父类的update方法更新其他字段:

def update(self, instance, validated_data):
    # 提取并处理密码字段
    password = validated_data.pop('password', None)
    password2 = validated_data.pop('password2', None)
    
    # 仅当密码存在且匹配时更新加密密码
    if password and password == password2:
        instance.set_password(password)
        instance.save()
    
    # 处理Profile嵌套字段更新
    profile_data = validated_data.pop('profile', {})
    profile = instance.profile
    for key, value in profile_data.items():
        setattr(profile, key, value)
    profile.save()
    
    # 更新用户模型的其他字段
    return super().update(instance, validated_data)

额外说明

  • DRF在执行update操作时会自动调用validate方法,所以密码匹配的逻辑无需重复编写,只需确保在update时处理加密即可。
  • set_password()方法会自动使用Django配置的密码哈希算法(默认PBKDF2)处理密码,不需要手动调用make_password(),因为set_password()内部已经封装了这个逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:42:47