Now, we will add the necessary code to configure the fields that we want to be included in the filtering, searching, and ordering features for each of the class-based views that retrieve the contents of each resource collection. Hence, we will make changes to all the classes with the List suffix in the views.py file: DroneCategoryList, DroneList, PilotList, and CompetitionList.
We will declare the following three class attributes in each of those classes:
- filter_fields: This attribute specifies a tuple of strings whose values indicate the field names that we want to be able to filter against. Under the hood, the Django REST framework will automatically create a rest_framework.filters.FilterSet class and associate it to the class-based view in which we are declaring the attribute. We will be able to filter against the field names included in the tuple of strings.
- search_fields: This attribute specifies a tuple of strings whose values indicate the text type field names that we want to include in the search feature. In all the usages, we will want to perform a starts-with match. In order to do this, we will include '^' as a prefix of the field name to indicate that we want to restrict the search behavior to a starts-with match.
- ordering_fields: This attribute specifies a tuple of strings whose values indicate the field names that the HTTP request can specify to sort the results. If the request doesn't specify a field for ordering, the response will use the default ordering fields specified in the model that is related to the class-based view.
Open the restful01/drones/views.py file. Add the following code after the last line that declares the imports, before the declaration of the DroneCategoryList class. The code file for the sample is included in the hillar_django_restful_07_03 folder in the restful01/drones/views.py file:
from rest_framework import filters from django_filters import AllValuesFilter, DateTimeFilter, NumberFilter
Add the following highlighted lines to the DroneList class declared in the views.py file. The next lines show the new code that defines the class. The code file for the sample is included in the hillar_django_restful_07_03 folder in the restful01/drones/views.py file:
class DroneCategoryList(generics.ListCreateAPIView): queryset = DroneCategory.objects.all() serializer_class = DroneCategorySerializer name = 'dronecategory-list' filter_fields = ( 'name', ) search_fields = ( '^name', ) ordering_fields = ( 'name', )
The changes in the DroneList class are easy to understand. We will be able to filter, search, and order by the name field.
Add the following highlighted lines to the DroneList class declared in the views.py file. The next lines show the new code that defines the class. The code file for the sample is included in the hillar_django_restful_07_03 folder in the restful01/drones/views.py file:
class DroneList(generics.ListCreateAPIView): queryset = Drone.objects.all() serializer_class = DroneSerializer name = 'drone-list' filter_fields = ( 'name', 'drone_category', 'manufacturing_date', 'has_it_competed', ) search_fields = ( '^name', ) ordering_fields = ( 'name', 'manufacturing_date', )
In the DroneList class, we specified many field names in the filter_fields attribute. We included 'drone_category' in the string tuple, and therefore, we will be able to include the ID values for this field in the filter.
The ordering_fields attribute specifies two field names for the tuple of strings, and therefore, we will be able to order the results by either name or manufacturing_date. Don't forget that we must take into account database optimizations when enabling fields to order by.
Add the following highlighted lines to the PilotList class declared in the views.py file. The next lines show the new code that defines the class. The code file for the sample is included in the hillar_django_restful_07_03 folder in the restful01/drones/views.py file:
class PilotList(generics.ListCreateAPIView): queryset = Pilot.objects.all() serializer_class = PilotSerializer name = 'pilot-list' filter_fields = ( 'name', 'gender', 'races_count', ) search_fields = ( '^name', ) ordering_fields = ( 'name', 'races_count' )
The ordering_fields attribute specifies two field names for the tuple of strings, and therefore, we will be able to order the results by either name or races_count.