Django - 我如何做 PATCH 请求 - ModelSerializer,RetrieveUpdateDestroyAPIView
Django - How can I do PATCH requests - ModelSerializer, RetrieveUpdateDestroyAPIView
我有一个 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_sha2560000$v7HiZeWnhmQj$ftiQyZCjMJ6pa26P5w72wQZvn+goEB94/lKyJ8LeKrM=
).
所以,我想发出 PATCH 请求而不发送密码。
您可以重写 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()
方法的情况下使用它们。
我有一个 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_sha2560000$v7HiZeWnhmQj$ftiQyZCjMJ6pa26P5w72wQZvn+goEB94/lKyJ8LeKrM=
).
所以,我想发出 PATCH 请求而不发送密码。
您可以重写 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()
方法的情况下使用它们。