子序列化程序如何从使用 Many=True 初始化的父序列化程序访问相应的字段值?

Kar*_*hik 5 django django-rest-framework

如果我们想用 初始化父序列化器many=True,那么子序列化器如何从其父序列化器访问相应的字段值?

class ChildSerializer(serializers.Serializer):
    field1 = serializers.CharField()

    def validate(self, data):
        # How to get the value of batch_key from the parent serializer (here self.batch_key)?
        if not self.batch_key == data['field1']:
            raise serializers.ValidationError('invalid field1')
        return data


class ParentSerializer(serializers.Serializer):
    child = ChildSerializer(many=True)
    batch_key = serializers.CharField()


class MyAPIView(APIView):

    def post(self, request):
        serializer = ParentSerializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        return
Run Code Online (Sandbox Code Playgroud)

请求数据如下:

[
   {
      "batch_key":"batch_key_value_1",
      "child":[
         {
            "field1":"value1"
         },
         {
            "field1":"value2"
         },
         {
            "field1":"value3"
         }
      ]
   },
   {
      "batch_key":"batch_key_value_2",
      "child":[
         {
            "field1":"value4"
         },
         {
            "field1":"value5"
         },
         {
            "field1":"value6"
         }
      ]
   }
]
Run Code Online (Sandbox Code Playgroud)

bdb*_*dbd 1

一种简单的方法是object-level validation..[DRF-docs]从父序列化程序运行所需的所有验证,因为您可以访问批处理密钥和子数据。

所以像这样:

class ParentSerializer(serializers.Serializer):
    child = ChildSerializer(many=True)
    batch_key = serializers.CharField()

    def validate(self, data):
        for child in data["child"]:
            if child["field1"] != data["batch_key"]:
                raise serializers.ValidationError({
                    "child": {
                        "field1": f"Invalid field1 {child['field1']}"
                    }
                })

        return data
Run Code Online (Sandbox Code Playgroud)

ParentSerializer当有 时这也有效many=True。这并不完美,因为它没有区分每个孩子的错误,因此将其留给您进行练习;)