[英]Django rest framework nested serializer partial update
序列化器:
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,)
create 和 update 都工作得很好,问题在于部分更新。 django 用户模型具有必需的用户名,我想将其设为可选。 有没有办法为这种情况启用部分更新?
例如,我想用 PUT 更新“foo”。
默认情况下,PUT 应提供所有必需的参数。 但 PATCH 不是。 因此,只要您可以使用 PATCH 而不是 PUT,您就根本不必更改代码。
我个人认为它的工作原理有点奇怪,PUT 需要所有非可选参数,但会单独保留可选参数。 因此,您可以编辑可选参数,同时保留其他可选参数,但不能对必需参数执行相同操作(我的意思是您显然可以只提供现有值,但是如果它们在您编辑时发生更改,您就被搞砸了,将强制更改它们背部)。 PATCH 对我来说更有意义。 你提供的任何论点都会改变,你不提供的任何论点都不会。 IMO PUT 应该清除未提供的任何可选参数,以便它是真正的替换而不是简单的替换必需和更新 (PUT) 可选。
我最终在 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。 不确定这是否是最优雅的解决方案,但它有效。 如果有人有更好的解决方案,请分享:)
实际上,以下代码已经支持部分更新:
instance.username = validated_data.get('username', instance.username)
这个' get ' 函数将从validated_data 中获取'username'字段。 如果它不存在,则将返回 instance.username。
用户序列号需要更改为类似
username = fields.CharField(required=False)
我认为在serializers.py 中定义和覆盖update()
方法时强制执行partial=True
就足够了,即:
def update(self, instance, validated_data, partial=True):
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.