From 539748cb69f4c239c687ed01628fc9e27ba517d9 Mon Sep 17 00:00:00 2001 From: Vlad Dragos Date: Thu, 19 Mar 2015 10:30:45 +0200 Subject: [PATCH 1/2] Add a check in CursorPagination.paginate_queryset to only apply the default the order_by method if the queryset is not ordered. --- rest_framework/pagination.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index b6be6b7cc..a9312d6ef 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -512,10 +512,11 @@ class CursorPagination(BasePagination): (offset, reverse, current_position) = self.cursor # Cursor pagination always enforces an ordering. - if reverse: - queryset = queryset.order_by(*_reverse_ordering(self.ordering)) - else: - queryset = queryset.order_by(*self.ordering) + if not queryset.ordered: + if reverse: + queryset = queryset.order_by(*_reverse_ordering(self.ordering)) + else: + queryset = queryset.order_by(*self.ordering) # If we have a cursor with a fixed position then filter by that. if current_position is not None: From bc29927f97dbc5916cb111dfa2eeee83d47eb4b2 Mon Sep 17 00:00:00 2001 From: Vlad Dragos Date: Thu, 19 Mar 2015 12:24:37 +0200 Subject: [PATCH 2/2] -- CursorPagination.get_ordering will return the queryset ordering if it exists. --- rest_framework/pagination.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index a9312d6ef..f4a59848c 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -6,6 +6,7 @@ be used for paginated responses. from __future__ import unicode_literals from base64 import b64encode, b64decode from collections import namedtuple +from django import VERSION as DJANGO_VERSION from django.core.paginator import InvalidPage, Paginator as DjangoPaginator from django.template import Context, loader from django.utils import six @@ -682,6 +683,27 @@ class CursorPagination(BasePagination): if hasattr(filter_cls, 'get_ordering') ] + if queryset.ordered: + if ordering_filters: + warnings.warn('The queryset is already ordered so' + 'the ordering provided by the filter class {}' + 'will be ignored'.format(filter_cls.__name__)) + + ordering = [] + if queryset.query.extra_order_by: + ordering.extend(queryset.query.extra_order_by) + elif queryset.query.order_by: + ordering.extend(queryset.query.order_by) + + elif queryset.query.default_ordering: + if DJANGO_VERSION[1] <= 5: + ordering.extend(queryset.query.model._meta.ordering) + else: + ordering.extend(queryset.query.get_meta().ordering) + + # Since the queryset is ordered we return the existing ordering. + return ordering + if ordering_filters: # If a filter exists on the view that implements `get_ordering` # then we defer to that filter to determine the ordering. @@ -711,6 +733,7 @@ class CursorPagination(BasePagination): if isinstance(ordering, six.string_types): return (ordering,) + return tuple(ordering) def _get_position_from_instance(self, instance, ordering):