Fixed issue 3957 where serializer_class wass accessed directly on the view in OrderingFilter backend instead of calling the view's get_serializer_class method

This commit is contained in:
Benjamin Mampaey 2016-02-25 12:11:22 +01:00
parent 450c76472b
commit df1fc8df7d
2 changed files with 51 additions and 2 deletions

View File

@ -227,8 +227,9 @@ class OrderingFilter(BaseFilterBackend):
if valid_fields is None:
# Default to allowing filtering on serializer fields
serializer_class = getattr(view, 'serializer_class')
if serializer_class is None:
try:
serializer_class = view.get_serializer_class()
except AssertionError:
msg = ("Cannot use %s on a view which does not have either a "
"'serializer_class' or 'ordering_fields' attribute.")
raise ImproperlyConfigured(msg % self.__class__.__name__)

View File

@ -5,6 +5,7 @@ import unittest
from decimal import Decimal
from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse
from django.db import models
from django.test import TestCase
@ -585,6 +586,53 @@ class OrderingFilterTests(TestCase):
)
OrderingFilterModel(title=title, text=text).save()
def test_get_valid_fields_from_explicit_serializer_class(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()
serializer_class = OrderingFilterSerializer
filter_backends = (filters.OrderingFilter, )
ordering_fields = None
queryset = OrderingFilterModel.objects.all()
view = OrderingListView()
backend = filters.OrderingFilter()
valid_fields = backend.get_valid_fields(queryset, view)
expected_valid_fields = [(field.source or field_name, field.label)
for (field_name, field) in OrderingFilterSerializer().fields.items()
if not getattr(field, 'write_only', False) and not field.source == '*']
self.assertEqual(valid_fields, expected_valid_fields)
def test_get_valid_fields_from_explicit_get_serializer_class(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()
filter_backends = (filters.OrderingFilter,)
ordering_fields = None
def get_serializer_class(self):
return OrderingFilterSerializer
queryset = OrderingFilterModel.objects.all()
view = OrderingListView()
backend = filters.OrderingFilter()
valid_fields = backend.get_valid_fields(queryset, view)
expected_valid_fields = [(field.source or field_name, field.label)
for (field_name, field) in OrderingFilterSerializer().fields.items()
if not getattr(field, 'write_only', False) and not field.source == '*']
self.assertEqual(valid_fields, expected_valid_fields)
def test_improperly_configured_error_from_get_valid_fields(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()
filter_backends = (filters.OrderingFilter,)
ordering_fields = None
serializer_class = None
queryset = OrderingFilterModel.objects.all()
view = OrderingListView()
backend = filters.OrderingFilter()
with self.assertRaises(ImproperlyConfigured):
backend.get_valid_fields(queryset, view)
def test_ordering(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()