Shift N' Tab Shift N' Tab - 16 days ago 6
Python Question

Reverse Filter Django Model with DRF

I have problem filtering in

and i am using
to work this serialized data.

What i want here is to get all herds record both with animal(s) in which the animal may had a
or an empty herd(s).

This is my models.

class Herd(models.Model):
name = models.CharField(max_length=25)
description = models.TextField(max_length=250, null=True)

created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)

class Animal(models.Model):
name = models.CharField(max_length=25)
species_type = models.CharField(max_length=25)
breed = models.CharField(max_length=25)

herd = models.ForeignKey(Herd, related_name='animals', on_delete=models.CASCADE)

created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)

class AnimalSerializer(serializers.ModelSerializer):

class Meta:
model = Animal
fields = [
read_only_fields = ['id', 'created_at', 'updated_at']

class HerdSerializer(serializers.ModelSerializer):
animals = AnimalSerializer(many=True, read_only=True)

class Meta:
model = Herd
fields = [
read_only_fields = ['created_at', 'updated_at']

This is my viewset which handle all crud operations.

class HerdViewset(viewsets.ModelViewSet):
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
queryset = Herd.objects.all()
serializer_class = HerdSerializer

Now when i browse the
i got the results of all herds with animals or empty herd(s). But the animals in some herd does not filter the
it still returns all animal which belong to that herd whether it
is goat, sheep, etc..


You can filter by species_type from Herd. Because you have defined a related_name in the foreign key.

try this

from django.db.models import Count, Q

  1. annotate is used to add an extra field to the results, so a new field animalCount is used to hold how many animals for that herd.
  2. Q is used to build complicated query condition, so for this case, Q(animals__species_type='Cow')|Q(animalCount=0) means, filter by the animals in the herd with species type 'Cow', or there is no animals in that herd.