Reputation: 311
I am trying to nest data from a single attribute of a related set in one of my DRF serializers.
So far, I am only able to do it through an intermediary serializer, which seems messy. I would like to do it directly.
As of now, this is the structure of my result:
[
{
"id": 1,
"name": "Pinot Noir",
"wine_list": [
{
"id": 1,
"wine": {
"id": 1,
"name": "Juan Gil"
}
}
]
}
]
The extra "wine_list" is redundant and surely unnecessary. I have achieved this with the following code.
These are my models. I have simplified them to include the necessary information only.
class Varietal(models.Model):
name = models.CharField(max_length=50)
class Wine(models.Model):
name = models.CharField(max_length=100)
class WineVarietal(models.Model):
wine = models.ForeignKey(Wine, on_delete=models.CASCADE)
varietal = models.ForeignKey(Varietal, on_delete=models.CASCADE)
These are the serializers I am working with now.
class VarietalDetailWineSerializer(ModelSerializer):
class Meta:
model = Wine
fields = ['id', 'name']
class VarietalDetailWineVarietalSerializer(ModelSerializer):
wine = VarietalDetailWineSerializer()
class Meta:
model = WineVarietal
fields = ['id', 'wine']
class VarietalDetailSerializer(ModelSerializer):
wine_list = VarietalDetailWineVarietalSerializer(source='winevarietal_set', many=True)
class Meta:
model = Varietal
fields = ['id', 'name', 'wine_list']
Ideally, I would get something like this:
[
{
"id": 1,
"name": "Pinot Noir",
"wine": [
{
"id": 1,
"name": "Juan Gil"
}
]
}
]
With code somewhat like this:
class VarietalDetailWineSerializer(ModelSerializer):
class Meta:
model = Wine
fields = [
'id',
'name',
]
class VarietalDetailSerializer(ModelSerializer):
wine = VarietalDetailWineSerializer(source='winevarietal_set.wine', many=True)
class Meta:
model = Varietal
fields = [
'id',
'name',
'wine',
]
But that source value is invalid.
Peace.
Upvotes: 0
Views: 1907
Reputation: 4630
One possible way to achieve this is to use serializerMethodField
.
class VarietalDetailSerializer(ModelSerializer):
wine = SerializerMethodField()
class Meta:
model = Varietal
fields = [
'id',
'name',
'image',
'description',
'wine',
'active'
]
def get_wine(self, varietal):
wine_varietals = varietal.winevarietal_set.all()
wine = [wine_varietals.wine for wine_varietals in wine_varietals]
return VarietalDetailWineSerializer(instance=wine, many=True).data
Our main target is to add many-to-many
fields response from a custom serializer method.
Upvotes: 1