【问题标题】:Django - How can I do PATCH requests - ModelSerializer, RetrieveUpdateDestroyAPIViewDjango - 我如何执行 PATCH 请求 - ModelSerializer、RetrieveUpdateDestroyAPIView
【发布时间】:2018-12-29 10:45:28
【问题描述】:

我有一个ProfileSerializer,它是一个ModelSerializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'password')

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer(required=True)

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = User.objects.create_user(**user_data, username=validated_data.get('username'))
        profile = Profile.objects.create(user=user, **validated_data)
        return profile

    def update(self, instance, validated_data):
        instance.dob = validated_data.get('dob', instance.dob)
        instance.karma = validated_data.get('karma', instance.karma)
        instance.username = validated_data.get('username', instance.username)
        user_data = validated_data.pop('user')
        instance.user.first_name = user_data.get('first_name', instance.user.first_name)
        instance.user.last_name = user_data.get('last_name', instance.user.last_name)
        instance.user.email = user_data.get('email', instance.user.email)
        instance.user.username = instance.username
        new_password = user_data.get('password')
        if new_password:
            instance.user.set_password(new_password)
        instance.user.save()
        instance.save()
        return instance

    class Meta:
        model = Profile
        fields = '__all__'

而且,我有一个名为 DetailProfile 的视图,它是一个 RetrieveUpdateDestroyAPIView

class DetailProfile(RetrieveUpdateDestroyAPIView):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer
    lookup_field = 'username'
    lookup_url_kwarg = 'username'

问题是每当我发出 PUT 请求时,我都必须发送包括密码在内的所有字段。现在,我从 GET 请求中获得的密码是 hashed。因此,如果我在 PUT 请求中发送相同的 hashed 密码,密码将被替换为该字符串(看起来像 pbkdf2_sha256$100000$v7HiZeWnhmQj$ftiQyZCjMJ6pa26P5w72wQZvn+goEB94/lKyJ8LeKrM=)。

所以,我想发出 PATCH 请求而不是发送密码。

【问题讨论】:

    标签: django authentication django-rest-framework http-put http-patch


    【解决方案1】:

    你可以重写put 方法并添加partial 参数,这会启用部分更新逻辑:

    class DetailProfile(RetrieveUpdateDestroyAPIView):
        queryset = Profile.objects.all()
        serializer_class = ProfileSerializer
        lookup_field = 'username'
        lookup_url_kwarg = 'username'
    
        def put(self, request, *args, **kwargs):
            kwargs['partial'] = True 
            return self.update(request, *args, **kwargs)
    

    BTW 补丁请求也适用于RetrieveUpdateDestroyAPIView。因此,如果您同时需要 PUT 和 PATCH,则可以使用它们而无需覆盖 put() 方法。

    【讨论】:

    • 这应该是ModelSerializer的函数?
    • @SreekarMouli 不,这是视图的一部分。
    • 这听起来可能很傻,但是既然我们重写了put 方法,那么请求方法应该是put 还是patch
    • @SreekarMouli 它应该是 PUT。如果您需要 PATCH,您可以使用 RetrieveUpdateDestroyAPIView 无需自定义。
    猜你喜欢
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2012-08-05
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多