- Django-REST, Python, Python Django

Customizing Filters in Django REST Framework

Prerequisite: Adding Filtering in APIs – Django REST Framework [lin needed article on published yet]Django filters facilitate filtering the queryset to retrieve the relevant results based on the values assigned to the filter fields. But, what if the user wants to retrieve details within a given range. Say, for example, the user needs to fetch detail of robots based on price range. Here comes the necessity of customizing the filters. Let’s create and apply a customized filter to the Robot model so that the user can retrieve robot details by providing robot category name, manufacturer name, currency, manufacturing date range, and/or price range.  We will create a new class named RobotFilter class, which is a subclass of django_filters.FilterSet class.  Let’s declare the importsPython3from django_filters import FilterSet, AllValuesFilterfrom django_filters import DateTimeFilter, NumberFilterNow, you can add the below code before the RobotList class.Python3class RobotFilter(FilterSet):    from_manufacturing_date = DateTimeFilter(field_name=’manufacturing_date’,                                             lookup_expr=’gte’)    to_manufacturing_date = DateTimeFilter(field_name=’manufacturing_date’,                                           lookup_expr=’lte’)    min_price = NumberFilter(field_name=’price’, lookup_expr=’gte’)    max_price = NumberFilter(field_name=’price’, lookup_expr=’lte’)    robotcategory_name = AllValuesFilter(field_name=’robot_category__name’)    manufacturer_name = AllValuesFilter(field_name=’manufacturer__name’)      class Meta:        model = Robot        fields = (            ‘name’,            ‘currency’,            ‘from_manufacturing_date’,            ‘to_manufacturing_date’,            ‘min_price’,            ‘max_price’,            ‘robotcategory_name’,            ‘manufacturer_name’,            )Let’s look at the attributes declared in the RobotFilter class.from_manufacturing_dateto_manufacturing_datemin_pricemax_pricerobotcategory_namemanufacturer_namefrom_manufacturing_date: It is a django_filters.DateTimeFilter instance attribute that filters the robots whose manufacturing_date value is greater than or equal to the specified DateTime value. Here in the DateTimeFilter, there are two parameters named field_name and lookup_expr. The field_name has the manufacturing_date (for filtering), and ‘gte’ (greater than or equal to) is applied to the lookup_expr.to_manufacturing_date: It is a django_filters.DateTimeFilter instance attribute that filters the robots whose manufacturing_date value is less than or equal to the specified DateTime value. Here in the DateTimeFilter, there are two parameters named field_name and lookup_expr. In the field_name, we mentioned the manufacturing_date, and ‘lte’ (less than or equal to) is applied to the lookup_expr.min_price: It is a django_filters.NumberFilter instance attribute that filters the robots whose price value is greater than or equal to the specified price value.max_price: It is a django_filters.NumberFilter instance attribute that filters the robots whose price value is less than or equal to the specified price value.robotcategory_name: It is a django_filters.AllValuesFilter instance attribute that filters the robots whose robot category name matches with the specified string value. You can notice that there is a double underscore (__) in the value provided to the field_name, between robot_category and name. The field_name uses the Django double underscore to read it as the name field for the RobotCategory model. This helps to retrieve the robot’s detail based on the robot category name rather than its pk id.manufacturer_name: It is a django_filters.AllValuesFilter instance attribute that filters the robots whose manufacturer name matches with the specified string value. The field_name uses the Django double underscore to read the value ‘manufacturer__name’ as the name field for the Manufacturer model. This helps to retrieve the robot’s detail based on the manufacturer name rather than its pk id.The RobotFilter class also defines a Meta inner class. This class has two attributes model and fields. The model attribute specifies the model (Robot) to filter. And, the fields attribute holds field names and filter names (as a tuple of strings) to include in the filters for the mentioned model (Robot). Let’s use the RobotFilter class in our RobotList class. The code as followsPython3class RobotList(generics.ListCreateAPIView):    queryset = Robot.objects.all()    serializer_class = RobotSerializer    name = ‘robot-list’        filter_class = RobotFilter    search_fields = (        ‘^name’,    )    ordering_fields = (        ‘price’,    )Let’s filter the robots within a manufacturing date. The HTTPie command ishttp “:8000/robot/?from_manufacturing_date=2019-10-01&to_manufacturing_date=2020-03-01”Output: Let’s filter the robots based on the robot category name and manufacturer name. The HTTPie command as followshttp “:8000/robot/?robotcategory_name=Articulated Robots&manufacturer_name=Fanuc”Output: Let’s filter the robots based on price range. The HTTPie command ishttp “:8000/robot/?min_price=10000&max_price=20000&currency=USD”Output: Let’s filter the robots using the browsable API feature. You can browse the below URL and click the filter button.http://127.0.0.1:8000/robot/You can populate the values to filter against robots. Sharing the screenshot below On clicking the submit button, you will get filtered results. Sharing the screenshot below  Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.  To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning – Basic Level Course