* Use get_serializer_class in ordering filter* Test improper configuration of ordering* Raise ImproperlyConfigured when missing get_serializer_class

* Use get_serializer_class in ordering filter
* Test improper configuration of ordering
* Raise ImproperlyConfigured when missing get_serializer_class
This commit is contained in:
Kennedy Mwenja 2016-05-26 11:59:13 +03:00 committed by Tom Christie
parent 2d20f09c0c
commit 592eea9b9e
2 changed files with 42 additions and 3 deletions

View File

@ -227,11 +227,14 @@ 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: # raised if no serializer_class was found
msg = ("Cannot use %s on a view which does not have either a "
"'serializer_class' or 'ordering_fields' attribute.")
"'serializer_class', an overriding 'get_serializer_class' "
"or 'ordering_fields' attribute.")
raise ImproperlyConfigured(msg % self.__class__.__name__)
valid_fields = [
(field.source or field_name, field.label)
for field_name, field in serializer_class().fields.items()

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
@ -754,6 +755,41 @@ class OrderingFilterTests(TestCase):
self.assertContains(response, 'verbose title')
def test_ordering_with_overridden_get_serializer_class(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
# note: no ordering_fields and serializer_class speficied
def get_serializer_class(self):
return OrderingFilterSerializer
view = OrderingListView.as_view()
request = factory.get('/', {'ordering': 'text'})
response = view(request)
self.assertEqual(
response.data,
[
{'id': 1, 'title': 'zyx', 'text': 'abc'},
{'id': 2, 'title': 'yxw', 'text': 'bcd'},
{'id': 3, 'title': 'xwv', 'text': 'cde'},
]
)
def test_ordering_with_improper_configuration(self):
class OrderingListView(generics.ListAPIView):
queryset = OrderingFilterModel.objects.all()
filter_backends = (filters.OrderingFilter,)
ordering = ('title',)
# note: no ordering_fields and serializer_class
# or get_serializer_class speficied
view = OrderingListView.as_view()
request = factory.get('/', {'ordering': 'text'})
with self.assertRaises(ImproperlyConfigured):
view(request)
class SensitiveOrderingFilterModel(models.Model):
username = models.CharField(max_length=20)