diff options
| author | Tom Christie | 2013-11-13 04:04:50 -0800 |
|---|---|---|
| committer | Tom Christie | 2013-11-13 04:04:50 -0800 |
| commit | fc1047e9b43ac4e27841cd2c34aac8fa6ced8c24 (patch) | |
| tree | ae51dec9e5ee4bcebbd22d1383602d66f06a996b | |
| parent | 8552e79d7b62ca7f0edd131d3049ca220d879d48 (diff) | |
| parent | e29942948f320088fbbf9a08cfd8579e0ef2e26f (diff) | |
| download | django-rest-framework-fc1047e9b43ac4e27841cd2c34aac8fa6ced8c24.tar.bz2 | |
Merge pull request #1224 from alexjg/allow-aggregate-ordering
Allow aggregate ordering
| -rw-r--r-- | rest_framework/filters.py | 1 | ||||
| -rw-r--r-- | rest_framework/tests/test_filters.py | 39 |
2 files changed, 40 insertions, 0 deletions
diff --git a/rest_framework/filters.py b/rest_framework/filters.py index e287a168..5c6a187c 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -124,6 +124,7 @@ class OrderingFilter(BaseFilterBackend): def remove_invalid_fields(self, queryset, ordering): field_names = [field.name for field in queryset.model._meta.fields] + field_names += queryset.query.aggregates.keys() return [term for term in ordering if term.lstrip('-') in field_names] def filter_queryset(self, request, queryset, view): diff --git a/rest_framework/tests/test_filters.py b/rest_framework/tests/test_filters.py index 379db29d..614f45cc 100644 --- a/rest_framework/tests/test_filters.py +++ b/rest_framework/tests/test_filters.py @@ -363,6 +363,12 @@ class OrdringFilterModel(models.Model): text = models.CharField(max_length=100) +class OrderingFilterRelatedModel(models.Model): + related_object = models.ForeignKey(OrdringFilterModel, + related_name="relateds") + + + class OrderingFilterTests(TestCase): def setUp(self): # Sequence of title/text is: @@ -472,3 +478,36 @@ class OrderingFilterTests(TestCase): {'id': 1, 'title': 'zyx', 'text': 'abc'}, ] ) + + def test_ordering_by_aggregate_field(self): + # create some related models to aggregate order by + num_objs = [2, 5, 3] + for obj, num_relateds in zip(OrdringFilterModel.objects.all(), + num_objs): + for _ in range(num_relateds): + new_related = OrderingFilterRelatedModel( + related_object=obj + ) + new_related.save() + + class OrderingListView(generics.ListAPIView): + model = OrdringFilterModel + filter_backends = (filters.OrderingFilter,) + ordering = 'title' + queryset = OrdringFilterModel.objects.all().annotate( + models.Count("relateds")) + + view = OrderingListView.as_view() + request = factory.get('?ordering=relateds__count') + response = view(request) + self.assertEqual( + response.data, + [ + {'id': 1, 'title': 'zyx', 'text': 'abc'}, + {'id': 3, 'title': 'xwv', 'text': 'cde'}, + {'id': 2, 'title': 'yxw', 'text': 'bcd'}, + ] + ) + + + |
