How do you use the django-filter package with a list of parameters?
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 filters
class NumberInFilter(filters.BaseInFilter, filters.NumberFilter):
pass
class 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
I found the following solution for my problem :)
https://gist.github.com/aBuder/654fb945f085b17358d8
from webapp.serializers import *
from rest_framework import viewsets
from rest_framework import filters
from django_filters import Filter, FilterSet
class 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
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.