Marcel
Marcel

Reputation: 175

Combining ordering and pagination in Django

I am using rest_framework.pagination.LimitOffsetPagination in combination with Django's sort filter (with filter_backends = [OrderingFilter] and ordering_fields in my view). The problem is that Django appears to be applying the sort on the pagination results, and not the other way around.

Analogy with a list:

If the results of the get_queryset are: ['b', 'e', 'c', 'a', 'd', 'f']

Pagination is applied first (e.g. with a limit of 3): ['b', 'e', 'c']

And then the results are sorted: ['b', 'c', 'e']

The result I would expect, however, is: ['a', 'b', 'c']

Any ideas how I can get sorting applied before pagination?

Thank you very much in advance.

Upvotes: 1

Views: 1575

Answers (1)

Horatiu Jeflea
Horatiu Jeflea

Reputation: 7404

Default list implementation applies filter before pagination, make sure you haven't overwritten list and not called super.

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

Also OrderingFilter is a weird name, as a filter is not meant to sort, but to remove some entries. Make sure you order in the queryset:

class AbcViewSet(ViewSet):
   queryset = Cde.objects.filter(...).order_by("id")

Upvotes: 1

Related Questions