How to Filter Children Model In Django RestFramework

Question:

I have been trying to build an api to filter out country_name. How can i filter multiple data from multiple model connected to each other through Foreign key.

when I query url https://www.localhost:8000/api/country/?country_name={}. It give me exact country that i want.

{
"count": 1,
"next": null,
"previous": null,
"results": [
    {
        "id": "7f0cf3bd-0a67-4c57-b192-5cf6cba8b203",
        "country_name": "Usa",
        "state": [
            {
                "id": "6a070973-11bd-4f9e-9bbf-652f171b028b",
                "state_name": "Alaska"
            },
            {
                "id": "6ed508ce-5ea0-441b-a02e-22cc9b70e6ae",
                "state_name": "Texsas"
            }
        ]
    }
  ]
}

I want same for state_name inside country_name if there are multiple states. How can I do it.

Models.py

from django.db import models
import uuid

# create your models here

# Forename Model
class COUNTRY(models.Model):
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  country_name = models.CharField(max_length=100, default=None)

  def __str__(self):
      return self.country_name

class STATE(models.Model):
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  state_name = models.CharField(max_length=100, default=None)

  # PARENT_COUNTRY
  parent_country = models.ForeignKey(COUNTRY, on_delete=models.PROTECT, 
                                       related_name='state')

  def __str__(self):
      return self.state_name

Serializer.py

from rest_framework import serializers
from .models import COUNTRY, STATE

# Name Serializer
class STATE_Serializer(serializers.ModelSerializer):
  class Meta:
    model = STATE
    fields = ["id", "state_name"]

class COUNTRY_Serializer(serializers.ModelSerializer):
  state = STATE_Serializer(many=True, required=True)
  class Meta:
    model = COUNTRY
    fields = ["id", "country_name", "state"]

Views.py

from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from .serializers import COUNTRY_Serializer,
from .models import COUNTRY

class Pagination(PageNumberPagination):
  page_size = 5
  page_size_query_param = 'page_size'
  max_page_size = 5


# view
class COUNTRY_VIEW(generics.ListAPIView):
  queryset = COUNTRY.objects.all()
  serializer_class = COUNTRY_Serializer
  filter_backends = [DjangoFilterBackend]
  filterset_fields = ['country_name']
  pagination_class = Pagination
Asked By: Stephen

||

Answers:

You can perform a related lookup on a ForeignKey or ManyToManyField with double underscore notation. Like in your view change filterset_fields to

class COUNTRY_VIEW(generics.ListAPIView):
  queryset = COUNTRY.objects.all()
  serializer_class = COUNTRY_Serializer
  filter_backends = [DjangoFilterBackend]
  filterset_fields = ['country_name', 'state__state_name']
  pagination_class = Pagination

In the URL use https://www.localhost:8000/api/country/?state__state_name={}

Note the double-underscore symbol.

Answered By: Asad Mahmood