From 53b100d03df848fd0a1190a83debee9ddba9df02 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Wed, 3 May 2017 12:49:39 -0400 Subject: [PATCH 1/2] Add failing test for filter backend mro --- requirements/requirements-optionals.txt | 2 +- tests/test_filters.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/requirements/requirements-optionals.txt b/requirements/requirements-optionals.txt index 5a0eb9cb2..83fe6d955 100644 --- a/requirements/requirements-optionals.txt +++ b/requirements/requirements-optionals.txt @@ -1,6 +1,6 @@ # Optional packages which may be used with REST framework. markdown==2.6.4 django-guardian==1.4.8 -django-filter==1.0.0 +django-filter==1.0.2 coreapi==2.2.4 coreschema==0.0.4 diff --git a/tests/test_filters.py b/tests/test_filters.py index 1b6f6f273..d2c11d258 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -201,6 +201,21 @@ class IntegrationTestFiltering(CommonFilteringTestCase): assert response.data == self.data assert len(w) == 0 + @unittest.skipUnless(django_filters, 'django-filter not installed') + def test_backend_mro(self): + class CustomBackend(filters.DjangoFilterBackend): + def filter_queryset(self, request, queryset, view): + assert False, "custom filter_queryset should run" + + class DFFilterFieldsRootView(FilterFieldsRootView): + filter_backends = (CustomBackend,) + + view = DFFilterFieldsRootView.as_view() + request = factory.get('/') + + with pytest.raises(AssertionError, message="custom filter_queryset should run"): + view(request).render() + @unittest.skipUnless(django_filters, 'django-filter not installed') def test_get_filtered_fields_root_view(self): """ From 01ffb8961de3c9b0531cedae2a524ce1a9927415 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Wed, 3 May 2017 12:51:44 -0400 Subject: [PATCH 2/2] Fix DjangoFilterBackend mro --- rest_framework/filters.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 20e196a14..429b79c77 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -50,12 +50,17 @@ if django_filters: DeprecationWarning ) return super(FilterSet, self).__init__(*args, **kwargs) + + DFBase = django_filters.rest_framework.DjangoFilterBackend + else: def FilterSet(): assert False, 'django-filter must be installed to use the `FilterSet` class' + DFBase = BaseFilterBackend -class DjangoFilterBackend(BaseFilterBackend): + +class DjangoFilterBackend(DFBase): """ A filter backend that uses django-filter. """ @@ -69,9 +74,7 @@ class DjangoFilterBackend(BaseFilterBackend): DeprecationWarning ) - from django_filters.rest_framework import DjangoFilterBackend - - return DjangoFilterBackend(*args, **kwargs) + return super(DjangoFilterBackend, cls).__new__(cls, *args, **kwargs) class SearchFilter(BaseFilterBackend):