Commit 98df9321 by Kieran Spear Committed by Tom Christie

Fix FilterSet proxy (#4620)

parent d92b24a0
......@@ -37,15 +37,32 @@ class BaseFilterBackend(object):
return []
class FilterSet(object):
def __new__(cls, *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
)
from django_filters.rest_framework import FilterSet
return FilterSet(*args, **kwargs)
return super(FilterSetMetaclass, cls).__new__(cls, name, bases, attrs)
_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):
......
......@@ -79,12 +79,23 @@ if django_filters:
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()
......@@ -297,6 +308,18 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
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):
"""
GET requests with filters that aren't configured should return 200.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment