I have an API endpoint returning pets and their owners.
Example Django models:
class Owner(models.Model):
name = models.CharField(max_length=200)
class Pet(models.Model):
owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
I've configured my API to return JSON data like this:
[
{
"id": 2,
"name": "Scotch",
"owner": {
"id": 2,
"name": "Ben"
}
},
{
"id": 3,
"name": "Fluffy",
"owner": {
"id": 1,
"name": "Fred"
}
},
{
"id": 1,
"name": "Spot",
"owner": {
"id": 1,
"name": "Fred"
}
}
]
Example DRF serializers:
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Owner
fields = ("id", "name")
class PetSerializer(serializers.HyperlinkedModelSerializer):
owner = OwnerSerializer()
class Meta:
model = Pet
fields = ("id", "name", "owner")
While that's all fine and dandy, I'd actually like to have an endpoint that returns a list of owners and their pets. So I'd get this data instead:
[
{
"id": 1,
"name": "Fred",
"pets": [
{ "id": 1, "name": "Spot" },
{ "id": 3, "name": "Fluffy" }
]
},
{
"id": 2,
"name": "Ben",
"pets": [
{ "id": 2, "name": "Scotch" }
]
}
]
How can I achieve that output?
You need to add pet_set
field to OwnerSerializer like this:
class PetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Pet
fields = ("id", "name")
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
pet_set = PetSerializer(many=True, read_only=True)
class Meta:
model = Owner
fields = ("id", "name", "pet_set")
This will work bacause many-to-one relation default reverse lookup name is <model>_set
or pet_set
in your case. You can change it by using related_name
:
class Pet(models.Model):
owner = models.ForeignKey(Owner, related_name='pets', on_delete=models.CASCADE)
In this case you can use pets
name inside serializer:
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
pets = PetSerializer(many=True, read_only=True)
Now in OwnerListView
you can use this new serializer:
class OwnerListView(ListAPIView):
queryset = Owner.objects.all()
serializer_class = OwnerSerializer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With