我刚刚遇到了同样的问题,让响应结构减少与底层模型结构的联系确实很有用。这是我的看法:
阅读很容易
Serializer fields有一个source参数,可以带点名来遍历属性。
class ABSerializer(serializers.ModelSerializer):
class Meta:
model = A
fields = ['name', 'age', 'salary']
salary = serializer.IntegerField(source='b.salary') # this is your related_name
写作是……没有官方支持
经过验证的数据将显示嵌套结构,并且标准的创建和更新方法会在尝试将数据字典分配给 OneToOneField 时阻塞。
好消息是您可以通过覆盖 create and update 方法来解决它。这是一个更新示例:
class ABSerializer(serializers.ModelSerializer):
class Meta:
model = A
fields = ['name', 'age', 'salary']
related_fields = ['b']
salary = serializer.IntegerField(source='b.salary') # this is your related_name
def update(self, instance, validated_data):
# Handle related objects
for related_obj_name in self.Meta.related_fields:
# Validated data will show the nested structure
data = validated_data.pop(related_obj_name)
related_instance = getattr(instance, related_obj_name)
# Same as default update implementation
for attr_name, value in data.items():
setattr(related_instance, attr_name, value)
related_instance.save()
return super(ABSerializer,self).update(instance, validated_data)
当然,这个例子非常简单,不做任何异常处理,也不能处理嵌套更深的对象……但你明白了。
另一种选择
您也可以create a read-write flavor of SerializerMethodField,它会同时考虑getter 和setter,但最终可能会变得更加冗长。
希望有帮助!