Skip to content

Commit 7c8b044

Browse files
committed
PendingDeprecationWarnings
- for renaming paginators without JsonApi prefix - for changes to attribute defaults
1 parent 5a8d67e commit 7c8b044

File tree

5 files changed

+157
-45
lines changed

5 files changed

+157
-45
lines changed

docs/usage.md

+18-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ by setting `REST_FRAMEWORK['DEFAULT_PAGINATION_CLASS']` and by setting `REST_FRA
6060
You can configure fixed values for the page size or limit -- or allow the client to choose the size or limit
6161
via query parameters.
6262

63-
Two pagination classes are available **but their names will change in release 3.0**:
63+
Two pagination classes are available *but their names will change in release 3.0 in order to implement a more
64+
consistent class naming style*:
6465
- `JsonApiPageNumberPagination` breaks a response up into pages that start at a given page number with a given size
6566
(number of items per page). It can be configured with the following attributes:
6667
- `page_query_param` (default `page[number]`)
@@ -71,7 +72,6 @@ Two pagination classes are available **but their names will change in release 3.
7172
- `max_page_size` (default `100`) enforces an upper bound on the `page_size_query_param`.
7273
Set it to `None` if you don't want to enforce an upper bound.
7374

74-
In release 3.0, `JsonApiPageNumberPagination` will be renamed `PageNumberPagination`.
7575
- `JsonApiLimitOffsetPagination` breaks a response up into pages that start from an item's offset in the viewset for
7676
a given number of items (the limit).
7777
It can be configured with the following attributes:
@@ -82,8 +82,23 @@ Two pagination classes are available **but their names will change in release 3.
8282
- `max_limit` (default `100`) enforces an upper bound on the limit.
8383
Set it to `None` if you don't want to enforce an upper bound.
8484

85-
In release 3.0, `JsonApiLimitOffsetPagination` will be renamed `LimitOffsetPagination`.
85+
##### Preparing for future renaming of paginators with default attributes
8686

87+
In release 3.0, the `JsonApi` prefix will be removed from the paginator names. If you currently use those (deprecated)
88+
names (`PageNumberPagination` or `LimitOffsetPagination`) or would like to prepare now for this change, you will want to
89+
explicitly override several of the class attributes.
90+
91+
To retain deprecated values for `PageNumberPagination` set `page_query_param = "page"` and
92+
`page_size_query_param = "page_size"`.
93+
94+
To prepare for the renaming of `JsonApiPageNumberPagination` use `PageNumberPagination` now with
95+
`page_query_param = "page[number]"` and `page_size_query_param = "page[size]"`.
96+
97+
To retain deprecated vales for `LimitOffsetPagination` set `max_limit = None`.
98+
99+
To prepare for the renaming of `JsonApiLimitOffsetPagination` to `LimitOffsetPagination` set `max_limit = 100`.
100+
101+
##### Examples
87102
These examples show how to configure the parameters to use non-standard names and different limits:
88103

89104
```python

example/settings/dev.py

-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868

6969
JSON_API_FORMAT_FIELD_NAMES = 'camelize'
7070
JSON_API_FORMAT_TYPES = 'camelize'
71-
JSON_API_STANDARD_PAGINATION = True
7271
REST_FRAMEWORK = {
7372
'PAGE_SIZE': 5,
7473
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',

example/settings/test.py

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
JSON_API_FIELD_NAMES = 'camelize'
1313
JSON_API_FORMAT_TYPES = 'camelize'
1414
JSON_API_PLURALIZE_TYPES = True
15-
# TODO: 13 tests fail when this is True because they use `page` and `page_size`. Fix them.
16-
JSON_API_STANDARD_PAGINATION = False
1715

1816
REST_FRAMEWORK.update({
1917
'PAGE_SIZE': 1,

example/tests/unit/test_pagination.py

+78-10
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,95 @@ def test_valid_offset_limit(self):
8282
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
8383
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
8484
def test_limit_offset_deprecation(self):
85-
with pytest.warns(DeprecationWarning) as record:
85+
with pytest.warns(PendingDeprecationWarning) as record:
8686
pagination.LimitOffsetPagination()
87-
assert len(record) == 2
87+
assert len(record) == 1
8888
assert 'LimitOffsetPagination will change in release 3.0' in str(record[0].message)
89-
assert 'JsonApiLimitOffsetPagination will be replaced by LimitOffsetPagination' \
90-
in str(record[1].message)
89+
90+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
91+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
92+
def test_jsonapi_limit_offset_deprecation(self):
93+
with pytest.warns(PendingDeprecationWarning) as record:
94+
pagination.JsonApiLimitOffsetPagination()
95+
assert len(record) == 1
96+
assert 'JsonApiLimitOffsetPagination will be renamed to LimitOffsetPagination'\
97+
in str(record[0].message)
98+
99+
class MyInheritedLimitOffsetPagination(pagination.LimitOffsetPagination):
100+
"""
101+
Inherit the default values
102+
"""
103+
pass
104+
105+
class MyOverridenLimitOffsetPagination(pagination.LimitOffsetPagination):
106+
"""
107+
Explicitly set max_limit to the "old" values.
108+
"""
109+
max_limit = None
110+
111+
def test_my_limit_offset_deprecation(self):
112+
with pytest.warns(PendingDeprecationWarning) as record:
113+
self.MyInheritedLimitOffsetPagination()
114+
assert len(record) == 1
115+
assert 'LimitOffsetPagination will change in release 3.0' in str(record[0].message)
116+
117+
with pytest.warns(None) as record:
118+
self.MyOverridenLimitOffsetPagination()
119+
assert len(record) == 0
91120

92121

93-
# TODO: This test fails under py27 but it's not clear why so just leave it out for now.
94122
class TestPageNumber:
95123
"""
96124
Unit tests for `pagination.JsonApiPageNumberPagination`.
97-
TODO: add unit tests for changing query parameter names, limits, etc.
98125
"""
99126

100127
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
101128
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
102129
def test_page_number_deprecation(self):
103-
with pytest.warns(DeprecationWarning) as record:
130+
with pytest.warns(PendingDeprecationWarning) as record:
104131
pagination.PageNumberPagination()
105-
assert len(record) == 2
132+
assert len(record) == 1
106133
assert 'PageNumberPagination will change in release 3.0' in str(record[0].message)
107-
assert 'JsonApiPageNumberPagination will be replaced by PageNumberPagination' \
108-
in str(record[1].message)
134+
135+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
136+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
137+
def test_jsonapi_page_number_deprecation(self):
138+
with pytest.warns(PendingDeprecationWarning) as record:
139+
pagination.JsonApiPageNumberPagination()
140+
assert len(record) == 1
141+
assert 'JsonApiPageNumberPagination will be renamed to PageNumberPagination' \
142+
in str(record[0].message)
143+
144+
class MyInheritedPageNumberPagination(pagination.PageNumberPagination):
145+
"""
146+
Inherit the default values
147+
"""
148+
pass
149+
150+
class MyOverridenPageNumberPagination(pagination.PageNumberPagination):
151+
"""
152+
Explicitly set page_query_param and page_size_query_param to the "old" values.
153+
"""
154+
page_query_param = "page"
155+
page_size_query_param = "page_size"
156+
157+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
158+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
159+
def test_my_page_number_deprecation(self):
160+
with pytest.warns(PendingDeprecationWarning) as record:
161+
self.MyInheritedPageNumberPagination()
162+
assert len(record) == 1
163+
assert 'PageNumberPagination will change in release 3.0' in str(record[0].message)
164+
165+
with pytest.warns(None) as record:
166+
self.MyOverridenPageNumberPagination()
167+
assert len(record) == 0
168+
169+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
170+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
171+
def test_my_jsonapi_page_number_deprecation(self):
172+
with pytest.warns(PendingDeprecationWarning) as record:
173+
pagination.JsonApiPageNumberPagination()
174+
assert len(record) == 1
175+
assert 'JsonApiPageNumberPagination will be renamed to PageNumberPagination' \
176+
in str(record[0].message)

rest_framework_json_api/pagination.py

+61-29
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,15 @@
99
from rest_framework.views import Response
1010

1111

12-
class JsonApiPageNumberPagination(PageNumberPagination):
12+
class _JsonApiPageNumberPagination(PageNumberPagination):
1313
"""
14-
A json-api compatible pagination format
14+
A json-api compatible pagination format.
15+
Use a private name for the implementation because the public name is pending deprecation.
1516
"""
1617
page_query_param = 'page[number]'
1718
page_size_query_param = 'page[size]'
1819
max_page_size = 100
1920

20-
def __init__(self):
21-
warnings.warn(
22-
'JsonApiPageNumberPagination will be replaced by PageNumberPagination in release 3.0'
23-
' See '
24-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
25-
DeprecationWarning)
26-
super(JsonApiPageNumberPagination, self).__init__()
27-
2821
def build_link(self, index):
2922
if not index:
3023
return None
@@ -58,24 +51,32 @@ def get_paginated_response(self, data):
5851
})
5952

6053

61-
class JsonApiLimitOffsetPagination(LimitOffsetPagination):
54+
class JsonApiPageNumberPagination(_JsonApiPageNumberPagination):
55+
"""
56+
current public name to be deprecated soon.
57+
"""
58+
def __init__(self):
59+
if type(self) == JsonApiPageNumberPagination:
60+
warnings.warn(
61+
'JsonApiPageNumberPagination will be renamed to PageNumberPagination in'
62+
' release 3.0. See '
63+
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
64+
PendingDeprecationWarning)
65+
super(_JsonApiPageNumberPagination, self).__init__()
66+
67+
68+
class _JsonApiLimitOffsetPagination(LimitOffsetPagination):
6269
"""
6370
A limit/offset based style. For example:
6471
http://api.example.org/accounts/?page[limit]=100
6572
http://api.example.org/accounts/?page[offset]=400&page[limit]=100
73+
74+
Use a private name for the implementation because the public name is pending deprecation.
6675
"""
6776
limit_query_param = 'page[limit]'
6877
offset_query_param = 'page[offset]'
6978
max_limit = 100
7079

71-
def __init__(self):
72-
warnings.warn(
73-
'JsonApiLimitOffsetPagination will be replaced by LimitOffsetPagination in release 3.0'
74-
' See '
75-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
76-
DeprecationWarning)
77-
super(JsonApiLimitOffsetPagination, self).__init__()
78-
7980
def get_last_link(self):
8081
if self.count == 0:
8182
return None
@@ -116,34 +117,65 @@ def get_paginated_response(self, data):
116117
})
117118

118119

119-
class PageNumberPagination(JsonApiPageNumberPagination):
120+
class JsonApiLimitOffsetPagination(_JsonApiLimitOffsetPagination):
121+
"""
122+
current public name to be deprecated soon.
123+
"""
124+
125+
def __init__(self):
126+
warnings.warn(
127+
'JsonApiLimitOffsetPagination will be renamed to LimitOffsetPagination in release 3.0'
128+
' See '
129+
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
130+
PendingDeprecationWarning)
131+
super(JsonApiLimitOffsetPagination, self).__init__()
132+
133+
134+
135+
class PageNumberPagination(_JsonApiPageNumberPagination):
120136
"""
121-
Deprecated paginator that uses different query parameters
137+
A soon-to-be-changed paginator that uses non-JSON:API query parameters (default:
138+
'page' and 'page_size' instead of 'page[number]' and 'page[size]').
122139
"""
123140
page_query_param = 'page'
124141
page_size_query_param = 'page_size'
125142

126143
def __init__(self):
127-
if self.page_query_param == 'page' or self.page_size_query_param == 'page_size':
144+
if type(self) == PageNumberPagination:
145+
warn = self.page_query_param == 'page' or self.page_size_query_param == 'page_size'
146+
else: # inherited class doesn't override the attributes?
147+
warn = ('page_query_param' not in type(self).__dict__ or
148+
'page_size_query_param' not in type(self).__dict__)
149+
if warn:
128150
warnings.warn(
129-
'PageNumberPagination will change in release 3.0 to default to use page[number] and'
130-
' page[size] query parameters. See '
151+
'PageNumberPagination will change in release 3.0 to change default values to: '
152+
'`page_query_param = "page[number]"` and `page_size_query_param = "page[size]"`. '
153+
'If you want to retain the current defaults you will need to explicitly set '
154+
'`page_query_param = "page"` and `page_size_query_param = "page_size"`. '
155+
'See '
131156
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
132-
DeprecationWarning)
157+
PendingDeprecationWarning)
158+
133159
super(PageNumberPagination, self).__init__()
134160

135161

136-
class LimitOffsetPagination(JsonApiLimitOffsetPagination):
162+
class LimitOffsetPagination(_JsonApiLimitOffsetPagination):
137163
"""
138164
Deprecated paginator that uses a different max_limit
139165
"""
140166
max_limit = None
141167

142168
def __init__(self):
143-
if self.max_limit is None:
169+
if type(self) == LimitOffsetPagination:
170+
warn = self.max_limit is None
171+
else:
172+
warn = 'max_limit' not in type(self).__dict__
173+
if warn:
144174
warnings.warn(
145-
'LimitOffsetPagination will change in release 3.0 to default to max_limit=100. '
175+
'LimitOffsetPagination will change in release 3.0 to default to `max_limit=100`. '
176+
'If you want to retain the current default you will need to explicitly set '
177+
'`max_limit = None`.'
146178
'See '
147179
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
148-
DeprecationWarning)
180+
PendingDeprecationWarning)
149181
super(LimitOffsetPagination, self).__init__()

0 commit comments

Comments
 (0)