DjangoRestFramework - передавать флаг частичности во вложенный сериализатор

Как передать флаг partial вложенным сериализаторам?

например, serializers.py

class ASerializer(serializers.Serializer):
    name = serializers.CharField()

    def validate(self, data):
        print("A", self.partial)
        return data


class BSerializer(serializers.Serializer):
    a = ASerializer(read_only=False)

    def validate(self, data):
        print("B", self.partial)
        return data  

views.py

class TestView(APIView):
    def get(self, request, format=None):
        content = {}
        return Response(content)

    def post(self, request, format=None):
        bsr = BSerializer(data=request.data, partial=True) # <- I want to pass the partial flag to the nested serializer as well
        if bsr.is_valid(raise_exception=True):
            return Response(bsr.data)
        else:
            return Response(bsr.error)  

передача {"a":{"name":"test"}} в TestView печатает

A False
B True  

В данном примере как передать флаг частичной обработки в ASerializer из BSerializer ?

Надеюсь, это работает... . Если вы получите ошибку типа name is not a field of your model, измените _name на _a и "name" на "a".

class BSerializer(serializers.Serializer):
    name = serializers.SerializerMethodField()
    
    def get_name(self, obj):
        # check your data, below is an example
        return ASerializer(obj.a.name, partial=self.partial, read_only=False).data if obj.a else None
    
    def validate(self, data):
        print("B", self.partial)
        return data 
    
    class Meta:
        model = YourModel
        fields = ['id', "name"] # add other fields

Не уверен, насколько это безопасно, но переопределение метода init, кажется, делает свое дело.

class BSerializer(serializers.Serializer):
    a = ASerializer(read_only=False)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["a"].partial = self.partial # <- update the partial flag here

    def validate(self, data):
        print("B", self.partial)
        return data
Вернуться на верх