From 0eb99e658063fcbe999d8e0eaa3978a9870731fb Mon Sep 17 00:00:00 2001 From: Kieran Spear Date: Mon, 24 Oct 2016 13:06:08 +0800 Subject: [PATCH 1/3] Add test to exercise FilterSet proxying --- tests/test_filters.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_filters.py b/tests/test_filters.py index 9795230d6e..12fb858958 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -79,12 +79,23 @@ class Meta: model = BaseFilterableItem fields = '__all__' + # Test the same filter using the deprecated internal FilterSet class. + class BaseFilterableItemFilterWithProxy(filters.FilterSet): + text = django_filters.CharFilter() + + class Meta: + model = BaseFilterableItem + fields = '__all__' + class BaseFilterableItemFilterRootView(generics.ListCreateAPIView): queryset = FilterableItem.objects.all() serializer_class = FilterableItemSerializer filter_class = BaseFilterableItemFilter filter_backends = (filters.DjangoFilterBackend,) + class BaseFilterableItemFilterWithProxyRootView(BaseFilterableItemFilterRootView): + filter_class = BaseFilterableItemFilterWithProxy + # Regression test for #814 class FilterFieldsQuerysetView(generics.ListCreateAPIView): queryset = FilterableItem.objects.all() @@ -296,6 +307,18 @@ def test_base_model_filter(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) + @unittest.skipUnless(django_filters, 'django-filter not installed') + def test_base_model_filter_with_proxy(self): + """ + The `get_filter_class` model checks should allow base model filters. + """ + view = BaseFilterableItemFilterWithProxyRootView.as_view() + + request = factory.get('/?text=aaa') + response = view(request).render() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) + @unittest.skipUnless(django_filters, 'django-filter not installed') def test_unknown_filter(self): """ From 96523b688339bd39d89af72993867b04c923d0e8 Mon Sep 17 00:00:00 2001 From: Kieran Spear Date: Mon, 24 Oct 2016 13:06:18 +0800 Subject: [PATCH 2/3] Fix FilterSet proxying --- rest_framework/filters.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 47d9a0342c..7859897351 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -37,15 +37,21 @@ def get_schema_fields(self, view): return [] -class FilterSet(object): - def __new__(cls, *args, **kwargs): - warnings.warn( - "The built in 'rest_framework.filters.FilterSet' is pending deprecation. " - "You should use 'django_filters.rest_framework.FilterSet' instead.", - PendingDeprecationWarning - ) - from django_filters.rest_framework import FilterSet - return FilterSet(*args, **kwargs) +if django_filters: + from django_filters.filterset import FilterSetMetaclass as DFFilterSetMetaclass + from django_filters.rest_framework.filterset import FilterSet as DFFilterSet + + class FilterSetMetaclass(DFFilterSetMetaclass): + def __new__(cls, name, bases, attrs): + warnings.warn( + "The built in 'rest_framework.filters.FilterSet' is pending deprecation. " + "You should use 'django_filters.rest_framework.FilterSet' instead.", + PendingDeprecationWarning + ) + return super(FilterSetMetaclass, cls).__new__(cls, name, bases, attrs) + + class FilterSet(six.with_metaclass(FilterSetMetaclass, DFFilterSet)): + pass class DjangoFilterBackend(BaseFilterBackend): From f4409fd2589fb67551499962dc97f7fef42a9cb5 Mon Sep 17 00:00:00 2001 From: Kieran Spear Date: Tue, 25 Oct 2016 10:25:01 +0800 Subject: [PATCH 3/3] Add friendly error message when django-filter isn't installed --- rest_framework/filters.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 7859897351..531531efc3 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -49,9 +49,20 @@ def __new__(cls, name, bases, attrs): PendingDeprecationWarning ) return super(FilterSetMetaclass, cls).__new__(cls, name, bases, attrs) - - class FilterSet(six.with_metaclass(FilterSetMetaclass, DFFilterSet)): - pass + _BaseFilterSet = DFFilterSet +else: + # Dummy metaclass just so we can give a user-friendly error message. + class FilterSetMetaclass(type): + def __init__(self, name, bases, attrs): + # Assert only on subclasses, so we can define FilterSet below. + if bases != (object,): + assert False, 'django-filter must be installed to use the `FilterSet` class' + super(FilterSetMetaclass, self).__init__(name, bases, attrs) + _BaseFilterSet = object + + +class FilterSet(six.with_metaclass(FilterSetMetaclass, _BaseFilterSet)): + pass class DjangoFilterBackend(BaseFilterBackend): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy