mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 18:08:03 +03:00 
			
		
		
		
	Merge pull request #1836 from jpadilla/filter-ordering
Preserve default ordering when using filtering
This commit is contained in:
		
						commit
						f4e02446f9
					
				| 
						 | 
					@ -56,7 +56,6 @@ class DjangoFilterBackend(BaseFilterBackend):
 | 
				
			||||||
                class Meta:
 | 
					                class Meta:
 | 
				
			||||||
                    model = queryset.model
 | 
					                    model = queryset.model
 | 
				
			||||||
                    fields = filter_fields
 | 
					                    fields = filter_fields
 | 
				
			||||||
                    order_by = True
 | 
					 | 
				
			||||||
            return AutoFilterSet
 | 
					            return AutoFilterSet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -408,16 +408,61 @@ class SearchFilterTests(TestCase):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrdringFilterModel(models.Model):
 | 
					class OrderingFilterModel(models.Model):
 | 
				
			||||||
    title = models.CharField(max_length=20)
 | 
					    title = models.CharField(max_length=20)
 | 
				
			||||||
    text = models.CharField(max_length=100)
 | 
					    text = models.CharField(max_length=100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderingFilterRelatedModel(models.Model):
 | 
					class OrderingFilterRelatedModel(models.Model):
 | 
				
			||||||
    related_object = models.ForeignKey(OrdringFilterModel,
 | 
					    related_object = models.ForeignKey(OrderingFilterModel,
 | 
				
			||||||
                                       related_name="relateds")
 | 
					                                       related_name="relateds")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DjangoFilterOrderingModel(models.Model):
 | 
				
			||||||
 | 
					    date = models.DateField()
 | 
				
			||||||
 | 
					    text = models.CharField(max_length=10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        ordering = ['-date']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DjangoFilterOrderingTests(TestCase):
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        data = [{
 | 
				
			||||||
 | 
					            'date': datetime.date(2012, 10, 8),
 | 
				
			||||||
 | 
					            'text': 'abc'
 | 
				
			||||||
 | 
					        }, {
 | 
				
			||||||
 | 
					            'date': datetime.date(2013, 10, 8),
 | 
				
			||||||
 | 
					            'text': 'bcd'
 | 
				
			||||||
 | 
					        }, {
 | 
				
			||||||
 | 
					            'date': datetime.date(2014, 10, 8),
 | 
				
			||||||
 | 
					            'text': 'cde'
 | 
				
			||||||
 | 
					        }]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for d in data:
 | 
				
			||||||
 | 
					            DjangoFilterOrderingModel.objects.create(**d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_default_ordering(self):
 | 
				
			||||||
 | 
					        class DjangoFilterOrderingView(generics.ListAPIView):
 | 
				
			||||||
 | 
					            model = DjangoFilterOrderingModel
 | 
				
			||||||
 | 
					            filter_backends = (filters.DjangoFilterBackend,)
 | 
				
			||||||
 | 
					            filter_fields = ['text']
 | 
				
			||||||
 | 
					            ordering = ('-date',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        view = DjangoFilterOrderingView.as_view()
 | 
				
			||||||
 | 
					        request = factory.get('/')
 | 
				
			||||||
 | 
					        response = view(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            response.data,
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                {'id': 3, 'date': datetime.date(2014, 10, 8), 'text': 'cde'},
 | 
				
			||||||
 | 
					                {'id': 2, 'date': datetime.date(2013, 10, 8), 'text': 'bcd'},
 | 
				
			||||||
 | 
					                {'id': 1, 'date': datetime.date(2012, 10, 8), 'text': 'abc'}
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderingFilterTests(TestCase):
 | 
					class OrderingFilterTests(TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        # Sequence of title/text is:
 | 
					        # Sequence of title/text is:
 | 
				
			||||||
| 
						 | 
					@ -436,11 +481,11 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
                chr(idx + ord('b')) +
 | 
					                chr(idx + ord('b')) +
 | 
				
			||||||
                chr(idx + ord('c'))
 | 
					                chr(idx + ord('c'))
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            OrdringFilterModel(title=title, text=text).save()
 | 
					            OrderingFilterModel(title=title, text=text).save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ordering(self):
 | 
					    def test_ordering(self):
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = ('title',)
 | 
					            ordering = ('title',)
 | 
				
			||||||
            ordering_fields = ('text',)
 | 
					            ordering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					@ -459,7 +504,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_reverse_ordering(self):
 | 
					    def test_reverse_ordering(self):
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = ('title',)
 | 
					            ordering = ('title',)
 | 
				
			||||||
            ordering_fields = ('text',)
 | 
					            ordering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					@ -478,7 +523,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_incorrectfield_ordering(self):
 | 
					    def test_incorrectfield_ordering(self):
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = ('title',)
 | 
					            ordering = ('title',)
 | 
				
			||||||
            ordering_fields = ('text',)
 | 
					            ordering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					@ -497,7 +542,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_default_ordering(self):
 | 
					    def test_default_ordering(self):
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = ('title',)
 | 
					            ordering = ('title',)
 | 
				
			||||||
            oredering_fields = ('text',)
 | 
					            oredering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					@ -516,7 +561,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_default_ordering_using_string(self):
 | 
					    def test_default_ordering_using_string(self):
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = 'title'
 | 
					            ordering = 'title'
 | 
				
			||||||
            ordering_fields = ('text',)
 | 
					            ordering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					@ -536,7 +581,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
    def test_ordering_by_aggregate_field(self):
 | 
					    def test_ordering_by_aggregate_field(self):
 | 
				
			||||||
        # create some related models to aggregate order by
 | 
					        # create some related models to aggregate order by
 | 
				
			||||||
        num_objs = [2, 5, 3]
 | 
					        num_objs = [2, 5, 3]
 | 
				
			||||||
        for obj, num_relateds in zip(OrdringFilterModel.objects.all(),
 | 
					        for obj, num_relateds in zip(OrderingFilterModel.objects.all(),
 | 
				
			||||||
                                     num_objs):
 | 
					                                     num_objs):
 | 
				
			||||||
            for _ in range(num_relateds):
 | 
					            for _ in range(num_relateds):
 | 
				
			||||||
                new_related = OrderingFilterRelatedModel(
 | 
					                new_related = OrderingFilterRelatedModel(
 | 
				
			||||||
| 
						 | 
					@ -545,11 +590,11 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
                new_related.save()
 | 
					                new_related.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class OrderingListView(generics.ListAPIView):
 | 
					        class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
            model = OrdringFilterModel
 | 
					            model = OrderingFilterModel
 | 
				
			||||||
            filter_backends = (filters.OrderingFilter,)
 | 
					            filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
            ordering = 'title'
 | 
					            ordering = 'title'
 | 
				
			||||||
            ordering_fields = '__all__'
 | 
					            ordering_fields = '__all__'
 | 
				
			||||||
            queryset = OrdringFilterModel.objects.all().annotate(
 | 
					            queryset = OrderingFilterModel.objects.all().annotate(
 | 
				
			||||||
                models.Count("relateds"))
 | 
					                models.Count("relateds"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        view = OrderingListView.as_view()
 | 
					        view = OrderingListView.as_view()
 | 
				
			||||||
| 
						 | 
					@ -567,7 +612,7 @@ class OrderingFilterTests(TestCase):
 | 
				
			||||||
    def test_ordering_with_nonstandard_ordering_param(self):
 | 
					    def test_ordering_with_nonstandard_ordering_param(self):
 | 
				
			||||||
        with temporary_setting('ORDERING_PARAM', 'order', filters):
 | 
					        with temporary_setting('ORDERING_PARAM', 'order', filters):
 | 
				
			||||||
            class OrderingListView(generics.ListAPIView):
 | 
					            class OrderingListView(generics.ListAPIView):
 | 
				
			||||||
                model = OrdringFilterModel
 | 
					                model = OrderingFilterModel
 | 
				
			||||||
                filter_backends = (filters.OrderingFilter,)
 | 
					                filter_backends = (filters.OrderingFilter,)
 | 
				
			||||||
                ordering = ('title',)
 | 
					                ordering = ('title',)
 | 
				
			||||||
                ordering_fields = ('text',)
 | 
					                ordering_fields = ('text',)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user