Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-ormdjango-filter

Django filters to generates filter for list of items


I want to filter the field vehicle_type based on comma query params

{{url}}/vehicles-records-info/75d9ee1b-8a03-4697-82e7-2d96ef0a8c2d/?vehicle_type=Mixer,Lorry

However when I print the query the generated query is

...  AND "vehicle_type" IN (M, i, x, e, r, ,, L, o, y)) 

But the query should be

...  AND "vehicle_type" IN ('Mixer', 'Lorry')) 

Here are my code

Filter

class VehicularAccessRecordInformationFilter(django_filters.FilterSet):
    vehicle_type = django_filters.CharFilter(field_name='vehicle_type', lookup_expr='in')
    start_timestamp = django_filters.DateTimeFilter(field_name='timestamp', lookup_expr='gte')
    end_timestamp = django_filters.DateTimeFilter(field_name='timestamp', lookup_expr='lte')

    class Meta:
        model = VehicleAccessRecordInformation
        fields = ['vehicle_type', 'timestamp']
    ```


Solution

  • This may help:

    from django_filters import rest_framework as filters
    
    
    class CharInFilter(filters.BaseInFilter, filters.CharFilter):
        pass
    
    
    class VehicularAccessRecordInformationFilter(filters.FilterSet):
        vehicle_type = CharInFilter(field_name='vehicle_type')
        ...
    
        class Meta:
            model = VehicleAccessRecordInformation
            fields = ['vehicle_type', <other_fields>]
    

    BaseInFilter accepts multiple values separated by comma, and CharFilter defines a type for the values, i.e. you can use NumberFilter, ChoiceFilter, etc.

    So that ?vehicle_type=Mixer,Lorry evaluates to

    VehicleAccessRecordInformation.objects.filter(vehicle_type__in=['Mixer', 'Lorry']