Fix FilterSet proxy (#4620)

This commit is contained in:
Kieran Spear 2016-11-01 18:30:17 +08:00 committed by Tom Christie
parent d92b24a0b7
commit 98df932194
2 changed files with 49 additions and 9 deletions

View File

@ -37,15 +37,32 @@ class BaseFilterBackend(object):
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)
_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):

View File

@ -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()
@ -296,6 +307,18 @@ class IntegrationTestFiltering(CommonFilteringTestCase):
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):
"""