串行器:
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('foo', 'bar')
class UserSerializer(serializers.ModelSerializer):
userprofile = ProfileSerializer(partial=True)
class Meta:
model = User
fields = ('username', 'password', 'email', 'userprofile')
def create(self, validated_data):
profile_data = validated_data.pop('userprofile')
user = User.objects.create(**validated_data)
UserProfile.objects.create(user=user, **profile_data)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('userprofile')
profile = instance.userprofile
instance.username = validated_data.get('username', instance.username)
instance.email = validated_data.get('email', instance.email)
instance.save()
profile.foo = profile_data.get('foo', profile.foo)
profile.bar = profile_data.get('bar', profile.bar)
profile.save()
return instance
查看:
class UsersViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
创建和更新都运行得很好,问题在于部分更新。 django用户模型具有所需的用户名,我想使其成为可选项。 有没有办法为这种情况启用部分更新?
例如,我想用PUT更新" foo"。
答案 0 :(得分:6)
默认情况下,PUT应提供所有必需的参数。但PATCH不是。因此,只要您使用PATCH而不是PUT就可以了,您根本不必更改代码。
我个人认为这有点奇怪,PUT要求所有参数都不是可选的,但会单独留下可选参数。所以你可以编辑可选参数,同时只留下其他可选参数,但不能用必需的参数做同样的事情(我的意思是你显然可以只提供现有的值,但是如果你在编辑时它们发生了变化,你就会被搞砸了改回来)。 PATCH对我来说更有意义。您提供的任何争论都将被更改,而您所提供的任何争论都不会被取消。 IMO PUT应该删除任何未提供的可选参数,以便它是一个真正的替换,而不是简单的替换需要和更新(PUT)可选。
答案 1 :(得分:4)
我最终覆盖了UsersViewSet中的get_serializer:
def get_serializer(self, instance=None, data=None, many=False, partial=False):
"""If request is not PUT, allow partial updates."""
if self.request.method == 'PUT':
return UserSerializer(instance=instance, data=data, many=many, partial=True)
else:
return UserSerializer(instance=instance, data=data, many=many, partial=partial)
如果request.method是PUT,则强制部分为True。不确定这是否是最优雅的解决方案,但它确实有效。 如果任何人有更好的解决方案,请分享:)
答案 2 :(得分:1)
实际上,以下代码已经支持部分更新:
instance.username = validated_data.get('username', instance.username)
此获取'功能将从 validated_data 获取'用户名'字段。如果它不存在,则返回instance.username。
答案 3 :(得分:1)
用户seriliazer需要改为
username = fields.CharField(required=False)
答案 4 :(得分:0)
我认为在 serializers.py 中定义和覆盖partial=True
方法时,只需执行update()
,即:
def update(self, instance, validated_data, partial=True):
...