diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 2a25378a0..4a7c3c092 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -112,7 +112,12 @@ class DjangoFilterBackend(BaseFilterBackend): filter_class = self.get_filter_class(view, queryset) if filter_class: - return filter_class(request.query_params, queryset=queryset).qs + # Inspired by @leo-the-manic goo.gl/3LoFIj + return filter_class( + dict([(param[0], len(param[1]) == 1 and param[1][0] or param[1]) + for param in request.query_params.lists()]), + queryset=queryset + ).qs return queryset diff --git a/tests/test_filters.py b/tests/test_filters.py index b72d95691..5725785d0 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -37,11 +37,17 @@ if django_filters: class SeveralFieldsFilter(django_filters.FilterSet): text = django_filters.CharFilter(lookup_type='icontains') decimal = django_filters.NumberFilter(lookup_type='lt') + decimal_in = django_filters.MethodFilter(action="filter_decimal_in") date = django_filters.DateFilter(lookup_type='gt') class Meta: model = FilterableItem - fields = ['text', 'decimal', 'date'] + fields = ['text', 'decimal', 'decimal_in', 'date'] + + def filter_decimal_in(self, qs, values): + if not hasattr(values, '__iter__'): + values = (values,) + return qs.filter(decimal__in=values) class FilterClassRootView(generics.ListCreateAPIView): queryset = FilterableItem.objects.all() @@ -209,6 +215,16 @@ class IntegrationTestFiltering(CommonFilteringTestCase): expected_data = [f for f in self.data if Decimal(f['decimal']) < search_decimal] self.assertEqual(response.data, expected_data) + # Tests that the decimal_in filter set with 'in' in the filter class works + search_decimal_in = ['1.25', '2.25'] + request = factory.get('/', { + 'decimal_in': search_decimal_in, + }) + response = view(request).render() + self.assertEqual(response.status_code, status.HTTP_200_OK) + expected_data = [f for f in self.data if f['decimal'] in search_decimal_in] + self.assertEqual(response.data, expected_data) + # Tests that the date filter set with 'gt' in the filter class works. search_date = datetime.date(2012, 10, 2) request = factory.get('/', {'date': '%s' % search_date}) # search_date str: '2012-10-02'