How do you use the django-filter package with a list of parameters? How do you use the django-filter package with a list of parameters? django django

How do you use the django-filter package with a list of parameters?


I found the following solution for my problem :)

https://gist.github.com/aBuder/654fb945f085b17358d8

from webapp.serializers import *from rest_framework import viewsetsfrom rest_framework import filtersfrom django_filters import Filter, FilterSetclass ListFilter(Filter):    def filter(self, qs, value):        if not value:            return qs        # For django-filter versions < 0.13, use lookup_type instead of lookup_expr        self.lookup_expr = 'in'        values = value.split(',')        return super(ListFilter, self).filter(qs, values)class AccommodationFilter(FilterSet):    ids = ListFilter(name='id')    accommodationType_ids = ListFilter(name='accommodationType_id')    class Meta:        model = Accommodation        fields = ['ids', 'accommodationType_ids']class AccommodationViewSet(viewsets.ReadOnlyModelViewSet):    """        REST API endpoint for 'accommodation' resource    """    queryset = Accommodation.objects.all()    serializer_class = AccommodationSerializer    filter_backends = (filters.DjangoFilterBackend,)    filter_class = AccommodationFilter


I know it is an old question, but might be worth it to give an updated answer.

Django-filter contributors have added a field called BaseInFilter which you can combine with other filters to validate the content.

See the docs:https://django-filter.readthedocs.io/en/latest/ref/filters.html#baseinfilter

For example, this would work in your case:

from django_filters import rest_framework as filtersclass NumberInFilter(filters.BaseInFilter, filters.NumberFilter):    passclass AccommodationFilter(filters.FilterSet):    accommodationType_id_in = NumberInFilter(field_name='accommodationType_id', lookup_expr='in')    class Meta:        model = Accommodation        fields = ['accommodationType_id_in', ]

Then you would be able to filter by a list of ids: http://localhost:8000/accommodations?accommodationType_id_in=1,2


Now there is an even simpler way to achieve this. Deep within the django-filter documentation, it mentions that you can use "a dictionary of field names mapped to a list of lookups".

Your code would be updated like so:

class AccommodationViewSet(viewsets.ReadOnlyModelViewSet):    """        REST API endpoint for 'accommodation' resource    """    queryset = Accommodation.objects.all()    serializer_class = AccommodationSerializer    filter_backends = (filters.DjangoFilterBackend,)    filter_fields = {        'accommodationType_id': ["in", "exact"], # note the 'in' field        'name': ["exact"]    }

Now in the URL you would add __in to the filter before supplying your list of parameters and it would work as you expect:

http://localhost:8000/accommodations?accommodationType_id__in=1,2

The django-filter documentation on what lookup filters are available is quite poor, but the in lookup filter is mentioned in the Django documentation itself.