Working with different types of Django filters

Now, we will create a customized filter that we will apply to the Competition model. We will code the new CompetitionFilter class, specifically, a subclass of the rest_framework.filters.FilterSet class.

Open the restful01/drones/views.py file. Add the following code before the declaration of the CompetitionList 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 CompetitionFilter(filters.FilterSet): 
    from_achievement_date = DateTimeFilter( 
        name='distance_achievement_date', lookup_expr='gte') 
    to_achievement_date = DateTimeFilter( 
        name='distance_achievement_date', lookup_expr='lte') 
    min_distance_in_feet = NumberFilter( 
        name='distance_in_feet', lookup_expr='gte') 
    max_distance_in_feet = NumberFilter( 
        name='distance_in_feet', lookup_expr='lte') 
    drone_name = AllValuesFilter( 
        name='drone__name') 
    pilot_name = AllValuesFilter( 
        name='pilot__name') 
 
    class Meta: 
        model = Competition 
        fields = ( 
            'distance_in_feet', 
            'from_achievement_date', 
            'to_achievement_date', 
            'min_distance_in_feet', 
            'max_distance_in_feet', 
            # drone__name will be accessed as drone_name 
            'drone_name', 
            # pilot__name will be accessed as pilot_name 
            'pilot_name', 
            )

The CompetitionFilter class declares the following class attributes:

  • from_achievement_date: This attribute is a django_filters.DateTimeFilter instance that allows the request to filter the competitions whose achievement_date DateTime value is greater than or equal to the specified DateTime value. The value specified in the name argument indicates the field to which the DateTime filter is applied, 'distance_achievement_date', and the value for the lookup_expr argument indicates the lookup expression, 'gte', which means greater than or equal to.
  • to_achievement_date: This attribute is a django_filters.DateTimeFilter instance that allows the request to filter the competitions whose achievement_date DateTime value is less than or equal to the specified DateTime value. The value specified in the name argument indicates the field to which the DateTime filter is applied, 'distance_achivement_date', and the value for the lookup_expr argument indicates the lookup expression, 'lte', which means less than or equal to.
  • min_distance_in_feet: This attribute is a django_filters.NumberFilter instance that allows the request to filter the competitions whose distance_in_feet numeric value is greater than or equal to the specified number. The value for the name argument indicates the field to which the numeric filter is applied, 'distance_in_feet', and the value for the lookup_expr argument indicates the lookup expression, 'gte', which means greater than or equal to.
  • max_distance_in_feet: This attribute is a django_filters.NumberFilter instance that allows the request to filter the competitions whose distance_in_feet numeric value is less than or equal to the specified number. The value for the name argument indicates the field to which the numeric filter is applied, 'distance_in_feet', and the value for the lookup_expr argument indicates the lookup expression, 'lte', which means less than or equal to.
  • drone_name: This attribute is a django_filters.AllValuesFilter instance that allows the request to filter the competitions whose drones' names match the specified string value. The value for the name argument indicates the field to which the filter is applied, 'drone__name'. Notice that there is a double underscore (__) between drone and name, and you can read it as the name field for the drone model or simply replace the double underscore with a dot and read drone.name. The name uses Django's double underscore syntax. However, we don't want the request to use drone__name to specify the filter for the drone's name. Hence, the instance is stored in the class attribute named drone_name, with just a single underscore between player and name, to make it more user-friendly. We will make configurations to make the browsable API display a drop-down with all the possible values for the drone's name to use as a filter. The drop-down will only include the drones' names that have registered competitions.
  • pilot_name: This attribute is a django_filters.AllValuesFilter instance that allows the request to filter the competitions whose pilots' names match the specified string value. The value for the name argument indicates the field to which the filter is applied, 'pilot__name'. The name uses Django's double underscore syntax. As happened with drone_name, we don't want the request to use pilot__name to specify the filter for the pilot's name, and therefore, we stored the instance in the class attribute named pilot_name, with just a single underscore between pilot and name. The browsable API will display a drop-down with all the possible values for the pilot's name to use as a filter. The drop-down will only include the pilots' names that have registered competitions because we used the AllValuesFilter class.

The CompetitionFilter class defines a Meta inner class that declares the following two attributes:

  • model: This attribute specifies the model related to the filter set, that is, the Competition class.
  • fields: This attribute specifies a tuple of strings whose values indicate the field names and filter names that we want to include in the filters for the related model. We included 'distance_in_feet' and the names for all the previously explained filters. The string 'distance_in_feet' refers to the field with this name. We want to apply the default numeric filter that will be built under the hood to allow the request to filter by an exact match on the distance_in_feet field. This way, the request will have plenty of options to filter competitions.

Now, add the following highlighted lines to the CompetitionList 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 CompetitionList(generics.ListCreateAPIView): 
    queryset = Competition.objects.all() 
    serializer_class = PilotCompetitionSerializer 
    name = 'competition-list' 
    filter_class = CompetitionFilter 
    ordering_fields = ( 
        'distance_in_feet', 
        'distance_achievement_date', 
        ) 

The filter_class attribute specifies CompetitionFilter as its value, that is, the FilterSet subclass that declares the customized filters that we want to use for this class-based view. In this case, the code didn't specify a tuple of strings for the filter_class attribute because we have defined our own FilterSet subclass.

The ordering_fields tuple of strings specifies the two field names that the request will be able to use for ordering the competitions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.0