Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialization of parent model including child models

I have models - Commodity, Clother and child models, as Acessories, Outwear, etc.:

class Commodity(models.Model):
    atribute = models.CharField()

class Clother(models.Model):
    commodity = models.ForeignKey(Commodity)
    clother_atribute = models.CharField()

class Acessories(models.Model):
    clother = models.ForeignKey(Clother)
    acessories_atribute = models.CharField() 

class Outwear(models.Model):
    clother = models.ForeignKey(Clother)
    outwear_atribute = models.CharField()

How can I serialize the parent model Commodity to call all vertical dependencies? I suppose to query Commodity id and get all Clother attributes and Acessories or Outwear attributes.

like image 588
D. Make Avatar asked Jun 21 '18 12:06

D. Make


3 Answers

If I understood your problem you can define ClotherSerializer. You can use depth = 1 to serialize nested objects in this serializer:

class ClotherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Clother
        fields = ('id', 'acessories_set', 'outwear_set')
        depth = 1

Later in your CommoditySerializer you can use ClotherSerializer to serialize clother and all it's relation:

class CommoditySerializer(serializers.ModelSerializer):
    clother_set = ClotherSerializer(many=True)
    class Meta:
        model = Commodity
        fields = ('id', 'clother_set')
like image 63
neverwalkaloner Avatar answered Oct 11 '22 20:10

neverwalkaloner


Alternatively, this can also be achieved using SerializerMethodField: http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

class ClotherSerializer(serializers.ModelSerializer):
    """
    Serializer for Clother data model.
    """
    acessories = serializers.SerializerMethodField()
    outwears = serializers.SerializerMethodField()

    class Meta:
        model = Clother
        fields = ('id', 'acessories', 'outwears')

    def get_acessories(self, clother):
        return AcessoriesSerializer(clother.acessories_set.all(), many=True).data

    def get_outwears(self, clother):
        return OutwearSerializer(clother.outwear_set.all(), many=True).data


class CommoditySerializer(serializers.ModelSerializer):
    """
    Serializer for Commodity data model.
    """
    clother = serializers.SerializerMethodField()

    class Meta:
        model = Commodity
        fields = ('id', 'clother')

    def get_clother(self, commodity):
        return ClotherSerializer(commodity.clother_set.all(), many=True).data
like image 42
mrehan Avatar answered Oct 11 '22 20:10

mrehan


You can use the drf-writable-nested [GitHub] package for that and specify in a serializer how to serialize certain fields. By using another serializer, you thus specify that it it serialized by calling the serializer for these children:

class CommoditySerializer(WritableNestedModelSerializer):
    clother_set = ClotherSerializer(many=True)

    class Meta:
        model = Commodity
        fields = ("atribute", 'clother_set')


class ClotherSerializer(WritableNestedModelSerializer):

    class Meta:
        model = Clother
        fields = ("clother_atribute",)

Of course you can add more such relations, for example to specify Acessories for a Clother.

I advice you look at the GitHub page, and use this as a template for your own serializer.

like image 45
Willem Van Onsem Avatar answered Oct 11 '22 22:10

Willem Van Onsem