From 5cb335155a7f848f6d78af8d9a322ae5c05a8a3d Mon Sep 17 00:00:00 2001 From: Andreu Vallbona Plazas Date: Sat, 13 Apr 2019 11:38:51 +0200 Subject: [PATCH] adding small clarification on nested serializiers via through models --- docs/api-guide/relations.md | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index 8665e80f6..e95421387 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -569,6 +569,65 @@ For more information see [the Django documentation on generic relations][generic ## ManyToManyFields with a Through Model +Example, given the following models: + + class Artist(models.Model): + name = models.CharField(max_length=180) + + def __str__(self): + return self.name + + + class Portfolio(models.Model): + user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) + name = models.CharField(max_length=180) + artists = models.ManyToManyField(Artist, through='Calification') + + def __str__(self): + return '{} - {}'.format(self.user, self.name) + + + class Calification(models.Model): + portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, related_name='califications') + artist = models.ForeignKey(Artist, on_delete=models.CASCADE) + rate = models.IntegerField(default=0) + added_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return '{} - {} - {}'.format(self.portfolio, self.artist, self.rate) + +We could serialize them as follows: + + class ArtistSerializer(serializers.ModelSerializer): + + class Meta: + model = Artist + fields = ('name', ) + + + class CalificationSerializer(serializers.ModelSerializer): + + artist = ArtistSerializer() + + class Meta: + model = Calification + fields = ('artist', 'rate', 'added_at') + + + class PortfolioSerializer(serializers.ModelSerializer): + + artists = CalificationSerializer(many=True, source='califications') + + class Meta: + model = Portfolio + fields = ('id', 'name', 'user', 'artists', ) + + +It's important to remember that it's easier if we set a ``related_name`` to the foreign_key we want to follow from the main model. +If we don't set it we would have to set the attribute ``source`` of the nested serializer ``CalificationSerializer`` as + + artists = CalificationSerializer(many=True, source='calification_set.all') + By default, relational fields that target a ``ManyToManyField`` with a ``through`` model specified are set to read-only.