diff options
| author | Tom Christie | 2015-01-22 15:15:52 +0000 | 
|---|---|---|
| committer | Tom Christie | 2015-01-22 15:15:52 +0000 | 
| commit | 408261ee02b176732b7f840f7042e7c24f3ecd27 (patch) | |
| tree | 0cc6b2a8d29b258b0f243bbd824902d7297f552f | |
| parent | 83a82b44a56a303d43a16dd675fae116e51b9d85 (diff) | |
| download | django-rest-framework-408261ee02b176732b7f840f7042e7c24f3ecd27.tar.bz2 | |
Support ordering attribute either on view or on pagination class for CursorPagination
| -rw-r--r-- | rest_framework/pagination.py | 24 | ||||
| -rw-r--r-- | tests/test_pagination.py | 1 | 
2 files changed, 20 insertions, 5 deletions
| diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index 58223f49..7b28b47f 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -427,16 +427,16 @@ class LimitOffsetPagination(BasePagination):  class CursorPagination(BasePagination): -    # Support case where ordering is already negative -    # Support tuple orderings +    # Support usage with OrderingFilter      # Determine how/if True, False and None positions work      cursor_query_param = 'cursor'      page_size = api_settings.PAGINATE_BY      invalid_cursor_message = _('Invalid cursor') +    ordering = None      def paginate_queryset(self, queryset, request, view=None):          self.base_url = request.build_absolute_uri() -        self.ordering = self.get_ordering() +        self.ordering = self.get_ordering(view)          # Determine if we have a cursor, and if so then decode it.          encoded = request.query_params.get(self.cursor_query_param) @@ -600,11 +600,25 @@ class CursorPagination(BasePagination):          encoded = _encode_cursor(cursor)          return replace_query_param(self.base_url, self.cursor_query_param, encoded) -    def get_ordering(self): +    def get_ordering(self, view):          """          Return a tuple of strings, that may be used in an `order_by` method.          """ -        return ('created',) +        ordering = getattr(view, 'ordering', getattr(self, 'ordering', None)) + +        assert ordering is not None, ( +            'Using cursor pagination, but no ordering attribute was declared ' +            'on the view or on the pagination class.' +        ) +        assert isinstance(ordering, (six.string_types, list, tuple)), ( +            'Invalid ordering. Expected string or tuple, but got {type}'.format( +                type=type(ordering).__name__ +            ) +        ) + +        if isinstance(ordering, six.string_types): +            return (ordering,) +        return ordering      def _get_position_from_instance(self, instance, ordering):          attr = getattr(instance, ordering[0]) diff --git a/tests/test_pagination.py b/tests/test_pagination.py index fffdcbe9..c05b4aba 100644 --- a/tests/test_pagination.py +++ b/tests/test_pagination.py @@ -459,6 +459,7 @@ class TestCursorPagination:          class ExamplePagination(pagination.CursorPagination):              page_size = 5 +            ordering = 'created'          self.pagination = ExamplePagination()          self.queryset = MockQuerySet([ | 
