Filter data in Django Rest Framework
Django REST Framework’s generic list view, by default, returns the entire query sets for a model manager. For real-world applications, it is necessary to filter the queryset to retrieve the relevant results based on the need. So, let’s discuss how to create a RESTful Web Service that provides filtering capabilities.
Note: You can refer The Browsable API section for Models, Serializers, and Views of Project used in the article
The DjangoFilterBackend class is used to filter the queryset based on a specified set of fields. This backend class automatically creates a FilterSet (django_filters.rest_framework.FilterSet) class for the given fields. We can also create our own FilterSet class with customized settings.
To configure filter backend classes in our Django Web Service, we need to install the django-filter package in our virtual environment. Make sure you quit the Django development server (Ctrl + C) and activate the virtual environment. Let’s run the below command.
pip install django-filter
After installation, we need to define the django_filters application to INSTALLED_APPS in the settings.py file.
As a next step, we need to set the DjangoFilterBackend class from django_filters as the default filter class. Let’s mention it to the REST_FRAMEWORK dictionary in the settings.py file.
Now our RESTful web service is configured to make use of the filtering feature provided by django_filters.rest_framework.DjangoFilterBackend class. Let’s filter the robot class that retrieves a list of robots. The RobotList class as follows:
Here, you can notice an attribute named filter_fileds where we specify the field name to filter against. Now, we can retrieve robots based on their category (robot_category) and/or manufacturer.
Let’s filter the robots based on the robot category. The HTTPie command is
Let’s try another HTTPie command that filters robots based on robot category and manufacturer. The HTTPie command is
Now let’s check the functionality in Browsable API. You can browse the below URL
You can click the Filters button in the top right corner to make use of the filter feature. It will display as shown below
On clicking the submit button you will get the result based on the populated filter fields as shown below.
The SearchFilter class supports a single query parameter-based searching feature, and it is based on the Django admin’s search function.
By default, SearchFilter class uses case-insensitive partial matches, and it may contain multiple search terms (should be whitespace and/or comma-separated). We can also restrict the search behavior by prepending various characters to the search_fields.
- ‘^’ Starts-with search.
- ‘=’ Exact matches.
- ‘@’ Full-text search. ( for Django’s PostgreSQL backend)
- ‘$’ Regex search
By default, the search parameter is named search, and you can override it with the SEARCH_PARAM setting. Let’s make use of SearchFilter class by adding the rest_framework.filters.SearchFilter class to the REST_FRAMEWORK dictionary.
Our RobotList class looks as follows:
The search_fields attribute specifies a tuple of strings, which indicates the field names that we want to include in the search feature.
Let’s search the robots, which starts with the name ‘IRB’. The HTTPie command is
The OrderingFilter class allows you to order the result based on the specified fields. By default, the query parameter is named ordering, and it can be overridden with the ORDERING_PARAM setting. The ordering_field attribute specifies a tuple of strings, which indicates the field names to sort the results.
If you don’t specify an ordering_fields attribute on the view, the filter class allows the user to filter on any readable fields specified by the serializer_class attribute. This permits the user to order against sensitive information such as password hash fields and so on, which may lead to unexpected data leakage. You can also specify a default order by setting an ordering attribute on the view. It can be either a string or a list/tuple of strings.
To make use of OrderingFilter class, we need to set the class as the default ordering filter class to the REST_FRAMEWORK dictionary.
Let’s mention the ordering_fields attribute on the RobotList class. The code as follows:
Now, let’s retrieve robots based on the increase in price order. The HTTPie command is