Repository: django-json-api/django-rest-framework-json-api

Issue:
spec compliance: pagination
Split #416 out into pagination improvements which comply with the jsonapi 1.0 [spec](http://jsonapi.org/format/#fetching-pagination)


Discussion:

Resolving patch:
diff --git a/rest_framework_json_api/pagination.py b/rest_framework_json_api/pagination.py
--- a/rest_framework_json_api/pagination.py
+++ b/rest_framework_json_api/pagination.py
@@ -1,6 +1,7 @@
 """
 Pagination fields
 """
+import warnings
 from collections import OrderedDict
 
 from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination
@@ -8,12 +9,12 @@
 from rest_framework.views import Response
 
 
-class PageNumberPagination(PageNumberPagination):
+class JsonApiPageNumberPagination(PageNumberPagination):
     """
     A json-api compatible pagination format
     """
-
-    page_size_query_param = 'page_size'
+    page_query_param = 'page[number]'
+    page_size_query_param = 'page[size]'
     max_page_size = 100
 
     def build_link(self, index):
@@ -49,7 +50,7 @@ def get_paginated_response(self, data):
         })
 
 
-class LimitOffsetPagination(LimitOffsetPagination):
+class JsonApiLimitOffsetPagination(LimitOffsetPagination):
     """
     A limit/offset based style. For example:
     http://api.example.org/accounts/?page[limit]=100
@@ -57,6 +58,7 @@ class LimitOffsetPagination(LimitOffsetPagination):
     """
     limit_query_param = 'page[limit]'
     offset_query_param = 'page[offset]'
+    max_limit = 100
 
     def get_last_link(self):
         if self.count == 0:
@@ -96,3 +98,34 @@ def get_paginated_response(self, data):
                 ('prev', self.get_previous_link())
             ])
         })
+
+
+class PageNumberPagination(JsonApiPageNumberPagination):
+    """
+    Deprecated paginator that uses different query parameters
+    """
+    page_query_param = 'page'
+    page_size_query_param = 'page_size'
+
+    def __init__(self):
+        warnings.warn(
+            'PageNumberPagination is deprecated. Use JsonApiPageNumberPagination '
+            'or create custom pagination. See '
+            'http://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
+            DeprecationWarning)
+        super(PageNumberPagination, self).__init__()
+
+
+class LimitOffsetPagination(JsonApiLimitOffsetPagination):
+    """
+    Deprecated paginator that uses a different max_limit
+    """
+    max_limit = None
+
+    def __init__(self):
+        warnings.warn(
+            'LimitOffsetPagination is deprecated. Use JsonApiLimitOffsetPagination '
+            'or create custom pagination. See '
+            'http://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
+            DeprecationWarning)
+        super(LimitOffsetPagination, self).__init__()


Test patch:
diff --git a/example/tests/unit/test_pagination.py b/example/tests/unit/test_pagination.py
--- a/example/tests/unit/test_pagination.py
+++ b/example/tests/unit/test_pagination.py
@@ -1,21 +1,23 @@
+import sys
 from collections import OrderedDict
 
+import pytest
 from rest_framework.request import Request
 from rest_framework.test import APIRequestFactory
 from rest_framework.utils.urls import replace_query_param
 
-from rest_framework_json_api.pagination import LimitOffsetPagination
+from rest_framework_json_api import pagination
 
 factory = APIRequestFactory()
 
 
 class TestLimitOffset:
     """
-    Unit tests for `pagination.LimitOffsetPagination`.
+    Unit tests for `pagination.JsonApiLimitOffsetPagination`.
     """
 
     def setup(self):
-        class ExamplePagination(LimitOffsetPagination):
+        class ExamplePagination(pagination.JsonApiLimitOffsetPagination):
             default_limit = 10
             max_limit = 15
 
@@ -76,3 +78,24 @@ def test_valid_offset_limit(self):
 
         assert queryset == list(range(offset + 1, next_offset + 1))
         assert content == expected_content
+
+    def test_limit_offset_deprecation(self):
+        with pytest.warns(DeprecationWarning) as record:
+            pagination.LimitOffsetPagination()
+        assert len(record) == 1
+        assert 'LimitOffsetPagination' in str(record[0].message)
+
+
+# TODO: This test fails under py27 but it's not clear why so just leave it out for now.
+@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
+                   reason="python2.7 fails for unknown reason")
+class TestPageNumber:
+    """
+    Unit tests for `pagination.JsonApiPageNumberPagination`.
+    TODO: add unit tests for changing query parameter names, limits, etc.
+    """
+    def test_page_number_deprecation(self):
+        with pytest.warns(DeprecationWarning) as record:
+            pagination.PageNumberPagination()
+        assert len(record) == 1
+        assert 'PageNumberPagination' in str(record[0].message)