Home > Net >  DjangoRestFramework - pass partial flag to nested serializer
DjangoRestFramework - pass partial flag to nested serializer

Time:08-05

How do I pass partial flag to nested serializers ?

for example , 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)  

passing {"a":{"name":"test"}} to TestView prints

A False
B True  

In this example how do I pass the partial flag to ASerializer from BSerializer ?

CodePudding user response:

I hope it works... . If you get an error like name is not a field of your model, change _name to _a and "name" to "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

CodePudding user response:

Not sure how safe this is but overriding the init method seems to do the job.

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
  • Related