Search code examples
djangodjango-rest-frameworkdjango-filterdjango-filters

Adding filter in django OrderingFilter


Is there a way to add a filter to queryset for a specific ordering field like "created" in OrderingFilter? I want to have this filter for ordering:

F('created').desc(nulls_last=True)

Here is my code:

class ProductFilter(filters.FilterSet):
    ordering = filters.OrderingFilter(fields=['price', 'created'])

    class Meta:
        model = Product

Solution

  • This worked for me:

    class NullsLastOrderingFilter(filters.OrderingFilter):
        def filter(self, qs, value):
            if value in ([], (), {}, '', None):
                return qs
    
            ordering = [self.get_ordering_value(param) for param in value]
    
            def filter_object(x):
                return F(x[1:]).desc(
                    nulls_last=True
                ) if x[0] == '-' else F(x).asc(
                    nulls_last=True
                )
    
            if ordering:
                ordering = map(filter_object, ordering)
                queryset = qs.order_by(*ordering)
    
            return queryset
    
    
    class ProductFilter(filters.FilterSet):
        ordering = NullsLastOrderingFilter(fields=['price', 'created'])
    
        class Meta:
            model = Product