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

使用Django ModelViewSet修改User模型用户密码不生效问题求助

问题根因

你当前的问题核心来自序列化器的更新逻辑缺失:

  • 你仅重写了UserSerializer的create方法,创建用户时调用了create_user会自动对明文密码做哈希存储;但ModelSerializer默认的update方法没有做密码特殊处理,会直接将传入的明文密码写入数据库。
  • Django User模型的密码校验逻辑会将用户输入的密码做哈希运算后,与数据库存储的哈希值比对,明文存储的密码自然无法通过校验,因此看起来密码没有更新、或者变成了未知值。
  • 密码修改后被登出Django后台是正常的安全机制:Django默认会在用户密码变更时,清空该用户所有已生效的会话,避免旧会话被恶意利用。

解决方案

修改serializers.py中的UserSerializer,重写update方法,手动处理密码的加密逻辑:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'password']

        extra_kwargs = {
            'password' : {
                'write_only':True,
                'required': True
            }
        }
    
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user) # create token for the user
        return user

    # 新增update方法处理更新逻辑
    def update(self, instance, validated_data):
        # 提取密码参数,不参与默认字段更新
        password = validated_data.pop('password', None)
        # 先更新其他普通字段
        instance = super().update(instance, validated_data)
        # 如果请求携带了密码参数,调用set_password做哈希存储
        if password:
            instance.set_password(password)
            instance.save()
            # 可选:如果需要旧token失效,删除原有token并生成新token返回给前端
            # instance.auth_token.delete()
            # Token.objects.create(user=instance)
        return instance

额外注意事项

  • PUT请求为全量更新,需要携带所有必填字段(比如username),如果只需要修改密码,建议使用PATCH请求做部分更新。
  • 检查请求头的Authorization拼写是否正确,部分框架对英式拼写Authorisation兼容不好,可能导致认证失败。
  • 生产环境建议单独做密码修改接口,增加旧密码校验逻辑,避免越权修改密码的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:45:03