Implementation of Filtering in GraphQL Python

Before learning about the implementation of filtering in GraphQL Python,  if you haven’t seen previous tutorials on this site I want you to first get familiar with the basics of GraphQL and learn how to perform CRUD operations with mutation. We are trying to write blogs on different topics in GraphQL using Python. So, we’ll provide links to our previous blogs in case you have missed the previous blogs.

Introduction

As the name suggests, filtering in GrapQL is used for filtering the data within our database.

Filtering in GraphQL is used for obtaining the information that matches certain criteria that you specify as your needs and requirements. GraphQL uses relay which is a client-side middleware between React and any GraphQL server. Using relay with graphene-django we will be able to implement pagination and filtering by default.

As mentioned before first visit the other two blogs that we’ve provided the link above and you are ready to follow this tutorial. So, let’s start this tutorial

Go and install django-filter

pip install django-filter

 

Implementation of Filtering

Go and edit your settings.py file as shown below

Books > settings.py

settings-file

Now, go and open Api > schema.py file and edit it as shown below:

import graphene
from graphene import relay
from .models import Book
from graphene_django import DjangoObjectType 
from django.core.exceptions import ObjectDoesNotExist
from graphene_django.filter import DjangoFilterConnectionField
from graphql import GraphQLError


class BookType(DjangoObjectType):
    class Meta:
        model = Book
        filter_fields = ['title', 'author']
        interfaces = (relay.Node, )
.
.
.
 
#At bottom of this file add the following lines of code

#filtering
class FilterBook(graphene.ObjectType):
    books = relay.Node.Field(BookType)
    all_books = DjangoFilterConnectionField(BookType)

 

Explanation

Here, filtering is available automatically with the use of a relay.Node and filter_fields specify the fields that we can use to filter and extract the data or information from our database.

And relay.Node.Field allows us to make a query on a single object by passing ID as an input while DjangoFilterConnectionField makes our query stronger by allowing us to filter with multiple options besides the fields available in our database model.

Before making a query let’s take a look at our new database as I have added some records to our previous database

graphql database

 

Filtering based on Author

Now, write some queries to filter records based on ‘author‘. Suppose we want to take out the details of books whose author is “Subin Bhattarai” (one of the authors of the book in our database). Go to http://127.0.0.1:8000/graphql/ and write your query as:

query {
  allBooks(author:"Subin Bhattarai"){
    edges{
      node{
        description
        id
        title
      }
    }	
  }
}

Output

filtering-on-author

 

As we can see in the output the records of books written by the author are filtered out among other records of books.

 

Filtering with some complex fields

We can provide some complex filtering conditions other than the fields available in our model. If we want to provide some complex filtering conditions make sure to use DjangoFilterConnectionField.

For this, you have to change filter_fields only as shown below:

class BookType(DjangoObjectType):
    class Meta:
        model = Book
        # filter_fields = ['title', 'author'] //previous version

        filter_fields = {                      
            'title': ['exact', 'icontains', 'istartswith'],
            'description': ['exact', 'icontains', 'istartswith'],
            'author': ['exact', 'icontains', 'istartswith'],
        }
        interfaces = (relay.Node, )

Suppose we want to filter out the records in which the first word of the title is ‘my‘.

Open your browser and go to this link http://127.0.0.1:8000/graphql/ and write your query as:

query{
  allBooks(title_Istartswith:"my"){
    edges{
      node{
        author
        title
        description
      }
    }
  }
}

Output

complex-filtering

As we can see that the books “my last ride” and “my last kingdom” have the initial letter “my“.

We pass the query that has a title starting with “my” with titile_Istartswith to filter the records.

 

Another example of complex filtering

Suppose we want to take out the records that contain the letter “this” in their description part. For this, we can write the query as:

query{
  allBooks(description_Icontains:"this"){
    edges{
      node{
        author
        title
        description
      }
    }
  }
}

Output

complex-filtering-twp

Here, three books have the letter “this” in their description part. We provide queries with description_Icontains to filter out the records.

 

Conclusion

Filtering is the process of selecting some records based on certain conditions. In python, django-filter is used for filtering the records. Also when we use relay.Node pagination and filtering are available by default.

We can provide complex filtering conditions using DjangoFilterConnectionField. So, the concept of filtering in GraphQL is essential.

 

Reference

To learn more about filtering see the documentation of graphene-python

Happy Learning 🙂

Leave a Comment