嵌套序列化器的访问创建方法

时间:2019-06-07 13:27:07

标签: python django python-3.x django-rest-framework django-serializer

我有一个父序列化器,其中包含两个子序列化器。子序列化器被重新使用,它们具有更新和创建的逻辑。

我的请求数据如下:

{
 'key1': [
          {'keyA': value},
          {'keyA': value}
        ]
 'key2': [
          {'keyB': value},
          {'keyB': value}
         ]
}

这些是我写的序列化器,

class ParentSerializer(serializers.Serializer):
    key1 = Key1Serializer(many=True)
    key2 = Key2Serializer(many=True)

    class Meta:
    ...

子序列化器,

class Key1Serializer(serializers.ModelSerializer):
    keyA = serializers.CharField(required=True)
    class Meta:
       model = Key1
       fields = ('keyA')
    list_serializer_class = MultipleKey1Serializer
class Key1Serializer(serializers.ModelSerializer):
    keyB = serializers.CharField(required=True)
    class Meta:
       model = Key2
       fields = ('keyB')
    list_serializer_class = MultipleKey2Serializer

列出序列化器,

class MultipleKey1Serializer(serializers.ListSerializer):
    def update(self, extra_params):
        for el in self.validated_data:
           ... #update logic
class MultipleKey2Serializer(serializers.ListSerializer):
    def create(self, extra_params):
        for el in self.validated_data:
           ... #create logic

这是我初始化父级序列化器的方式

serializer = ParentSerializer(data=request_data)
serializer.is_valid() # <- works perfectly, validates all the fields

因此嵌套的序列化程序可以完美地验证数据。现在,我要做的就是在Key1Serializer内部调用update方法,在Key2Serializer内部创建方法。

我尝试称其为懒惰方式,

serializer.data['key2'].create(params)

但这不是正确的方法。有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

因此,您已经发现,嵌套的序列化程序实例在验证后不会保存在任何位置,因此您需要手动创建它们。您可以在父级序列化程序的create方法中执行此操作:

def create(self, validated_data):
    k1_data = validated_data.pop('key1')
    k2_data = validated_data.pop('key2')

    instance = super().create(validated_data)

    serializer = Key1Serializer(k1_data, context=self.context, many=True)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    serializer2 = Key2Serializer(k2_data, context=self.context, many=True)
    serializer2.is_valid(raise_exception=True)
    serializer2.save()

    return instance