From 894a94ce707489f42ddd494655af26c4e5fa6b24 Mon Sep 17 00:00:00 2001 From: OmegaDroid Date: Mon, 23 Oct 2017 15:21:56 +0100 Subject: [PATCH] replaced '.' for '__' in dotted ordering sources --- rest_framework/filters.py | 2 +- tests/test_filters.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 28b6995ec..d30135d2e 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -199,7 +199,7 @@ class OrderingFilter(BaseFilterBackend): raise ImproperlyConfigured(msg % self.__class__.__name__) return [ - (field.source or field_name, field.label) + (field.source.replace('.', '__') or field_name, field.label) for field_name, field in serializer_class(context=context).fields.items() if not getattr(field, 'write_only', False) and not field.source == '*' ] diff --git a/tests/test_filters.py b/tests/test_filters.py index dc5b18068..bcfd7686a 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -320,6 +320,18 @@ class OrderingFilterSerializer(serializers.ModelSerializer): fields = '__all__' +class OrderingDottedRelatedSerializer(serializers.ModelSerializer): + related_text = serializers.CharField(source='related_object.text') + related_title = serializers.CharField(source='related_object.title') + + class Meta: + model = OrderingFilterRelatedModel + fields = ( + 'related_text', + 'related_title', + ) + + class DjangoFilterOrderingModel(models.Model): date = models.DateField() text = models.CharField(max_length=10) @@ -484,6 +496,24 @@ class OrderingFilterTests(TestCase): {'id': 2, 'title': 'yxw', 'text': 'bcd'}, ] + def test_ordering_by_dotted_source(self): + for obj in OrderingFilterModel.objects.all(): + OrderingFilterRelatedModel.objects.create(related_object=obj) + + class OrderingListView(generics.ListAPIView): + serializer_class = OrderingDottedRelatedSerializer + filter_backends = (filters.OrderingFilter,) + queryset = OrderingFilterRelatedModel.objects.all() + + view = OrderingListView.as_view() + request = factory.get('/', {'ordering': 'related_object__text'}) + response = view(request) + assert response.data == [ + {'related_title': 'zyx', 'related_text': 'abc'}, + {'related_title': 'yxw', 'related_text': 'bcd'}, + {'related_title': 'xwv', 'related_text': 'cde'}, + ] + def test_ordering_with_nonstandard_ordering_param(self): with override_settings(REST_FRAMEWORK={'ORDERING_PARAM': 'order'}): reload_module(filters)