Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7fa46c2

Browse files
n2ygksliverc
authored andcommitted
revert JSONAPI prefix to JsonApi for paginators. (#469)
Clarify deprecation warning of pagination classes
1 parent e8a735f commit 7fa46c2

File tree

7 files changed

+124
-76
lines changed

7 files changed

+124
-76
lines changed

‎CHANGELOG.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ any parts of the framework not mentioned in the documentation should generally b
2424
### Fixed
2525

2626
* Performance improvement when rendering relationships with `ModelSerializer`
27+
* Do not show deprecation warning when user has implemented custom pagination class overwriting default values.
28+
2729

2830
## [2.5.0] - 2018年07月11日
2931

@@ -40,6 +42,16 @@ any parts of the framework not mentioned in the documentation should generally b
4042
### Deprecated
4143

4244
* Deprecate `PageNumberPagination` and `LimitOffsetPagination`. Use `JsonApiPageNumberPagination` and `JsonApiLimitOffsetPagination` instead.
45+
* To retain deprecated values for `PageNumberPagination` and `LimitOffsetPagination` create new custom class like the following in your code base:
46+
```python
47+
class CustomPageNumberPagination(PageNumberPagination):
48+
page_query_param = "page"
49+
page_size_query_param = "page_size"
50+
51+
class CustomLimitOffsetPagination(LimitOffsetPagination):
52+
max_limit = None
53+
```
54+
and adjust `REST_FRAMEWORK['DEFAULT_PAGINATION_CLASS']` setting accordingly.
4355
* Deprecate `JSON_API_FORMAT_KEYS`, use `JSON_API_FORMAT_FIELD_NAMES`.
4456

4557
### Fixed

‎README.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ override ``settings.REST_FRAMEWORK``
161161
'PAGE_SIZE': 10,
162162
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
163163
'DEFAULT_PAGINATION_CLASS':
164-
'rest_framework_json_api.pagination.JSONAPIPageNumberPagination',
164+
'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
165165
'DEFAULT_PARSER_CLASSES': (
166166
'rest_framework_json_api.parsers.JSONParser',
167167
'rest_framework.parsers.FormParser',

‎docs/usage.md‎

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ REST_FRAMEWORK = {
1616
'PAGE_SIZE': 10,
1717
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
1818
'DEFAULT_PAGINATION_CLASS':
19-
'rest_framework_json_api.pagination.JSONAPIPageNumberPagination',
19+
'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
2020
'DEFAULT_PARSER_CLASSES': (
2121
'rest_framework_json_api.parsers.JSONParser',
2222
'rest_framework.parsers.FormParser',
@@ -50,6 +50,8 @@ DJA pagination is based on [DRF pagination](https://www.django-rest-framework.or
5050
When pagination is enabled, the renderer will return a `meta` object with
5151
record count and a `links` object with the next, previous, first, and last links.
5252

53+
Optional query parameters can also be provided to customize the page size or offset limit.
54+
5355
#### Configuring the Pagination Style
5456

5557
Pagination style can be set on a particular viewset with the `pagination_class` attribute or by default for all viewsets
@@ -59,35 +61,42 @@ You can configure fixed values for the page size or limit -- or allow the client
5961
via query parameters.
6062

6163
Two pagination classes are available:
62-
- `JSONAPIPageNumberPagination` breaks a response up into pages that start at a given page number
63-
with a given size (number of items per page). It can be configured with the following attributes:
64+
- `JsonApiPageNumberPagination` breaks a response up into pages that start at a given page number with a given size
65+
(number of items per page). It can be configured with the following attributes:
6466
- `page_query_param` (default `page[number]`)
6567
- `page_size_query_param` (default `page[size]`) Set this to `None` if you don't want to allow the client
6668
to specify the size.
69+
- `page_size` (default `REST_FRAMEWORK['PAGE_SIZE']`) default number of items per page unless overridden by
70+
`page_size_query_param`.
6771
- `max_page_size` (default `100`) enforces an upper bound on the `page_size_query_param`.
6872
Set it to `None` if you don't want to enforce an upper bound.
69-
- `JSONAPILimitOffsetPagination` breaks a response up into pages that start from an item's offset
70-
in the viewset for a given number of items (the limit).
73+
74+
- `JsonApiLimitOffsetPagination` breaks a response up into pages that start from an item's offset in the viewset for
75+
a given number of items (the limit).
7176
It can be configured with the following attributes:
7277
- `offset_query_param` (default `page[offset]`).
7378
- `limit_query_param` (default `page[limit]`).
79+
- `default_limit` (default `REST_FRAMEWORK['PAGE_SIZE']`) is the default number of items per page unless
80+
overridden by `limit_query_param`.
7481
- `max_limit` (default `100`) enforces an upper bound on the limit.
7582
Set it to `None` if you don't want to enforce an upper bound.
7683

77-
84+
##### Examples
7885
These examples show how to configure the parameters to use non-standard names and different limits:
7986

8087
```python
81-
from rest_framework_json_api.pagination import JSONAPIPageNumberPagination, JSONAPILimitOffsetPagination
88+
from rest_framework_json_api.pagination import JsonApiPageNumberPagination, JsonApiLimitOffsetPagination
8289

83-
class MyPagePagination(JSONAPIPageNumberPagination):
90+
class MyPagePagination(JsonApiPageNumberPagination):
8491
page_query_param = 'page_number'
85-
page_size_query_param = 'page_size'
92+
page_size_query_param = 'page_length'
93+
page_size = 3
8694
max_page_size = 1000
8795

88-
class MyLimitPagination(JSONAPILimitOffsetPagination):
96+
class MyLimitPagination(JsonApiLimitOffsetPagination):
8997
offset_query_param = 'offset'
9098
limit_query_param = 'limit'
99+
default_limit = 3
91100
max_limit = None
92101
```
93102

@@ -146,7 +155,7 @@ If you are also using [`rest_framework.filters.SearchFilter`](https://django-res
146155
(which performs single parameter searchs across multiple fields) you'll want to customize the name of the query
147156
parameter for searching to make sure it doesn't conflict with a field name defined in the filterset.
148157
The recommended value is: `search_param="filter[search]"` but just make sure it's
149-
`filter[_something_]` to comply with the jsonapi spec requirement to use the filter
158+
`filter[_something_]` to comply with the JSON:API spec requirement to use the filter
150159
keyword. The default is "search" unless overriden.
151160

152161
The filter returns a `400 Bad Request` error for invalid filter query parameters as in this example
@@ -446,7 +455,7 @@ class OrderSerializer(serializers.ModelSerializer):
446455

447456
```
448457

449-
In the [JSONAPI spec](http://jsonapi.org/format/#document-resource-objects),
458+
In the [JSON:API spec](http://jsonapi.org/format/#document-resource-objects),
450459
relationship objects contain links to related objects. To make this work
451460
on a serializer we need to tell the `ResourceRelatedField` about the
452461
corresponding view. Use the `HyperlinkedModelSerializer` and instantiate
@@ -584,7 +593,7 @@ class OrderSerializer(serializers.HyperlinkedModelSerializer):
584593
### RelationshipView
585594
`rest_framework_json_api.views.RelationshipView` is used to build
586595
relationship views (see the
587-
[JSONAPI spec](http://jsonapi.org/format/#fetching-relationships)).
596+
[JSON:API spec](http://jsonapi.org/format/#fetching-relationships)).
588597
The `self` link on a relationship object should point to the corresponding
589598
relationship view.
590599

‎example/settings/test.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
JSON_API_FIELD_NAMES = 'camelize'
1313
JSON_API_FORMAT_TYPES = 'camelize'
1414
JSON_API_PLURALIZE_TYPES = True
15+
1516
REST_FRAMEWORK.update({
1617
'PAGE_SIZE': 1,
1718
})

‎example/tests/unit/test_pagination.py‎

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
class TestLimitOffset:
1515
"""
16-
Unit tests for `pagination.JSONAPILimitOffsetPagination`.
16+
Unit tests for `pagination.JsonApiLimitOffsetPagination`.
1717
"""
1818

1919
def setup(self):
20-
class ExamplePagination(pagination.JSONAPILimitOffsetPagination):
20+
class ExamplePagination(pagination.JsonApiLimitOffsetPagination):
2121
default_limit = 10
2222
max_limit = 15
2323

@@ -79,33 +79,71 @@ def test_valid_offset_limit(self):
7979
assert queryset == list(range(offset + 1, next_offset + 1))
8080
assert content == expected_content
8181

82+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
83+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
8284
def test_limit_offset_deprecation(self):
8385
with pytest.warns(DeprecationWarning) as record:
8486
pagination.LimitOffsetPagination()
8587
assert len(record) == 1
86-
assert 'LimitOffsetPagination' in str(record[0].message)
88+
assert 'LimitOffsetPagination is deprecated' in str(record[0].message)
8789

90+
class MyInheritedLimitOffsetPagination(pagination.LimitOffsetPagination):
91+
"""
92+
Inherit the default values
93+
"""
94+
pass
95+
96+
class MyOverridenLimitOffsetPagination(pagination.LimitOffsetPagination):
97+
"""
98+
Explicitly set max_limit to the "old" values.
99+
"""
100+
max_limit = None
101+
102+
def test_my_limit_offset_deprecation(self):
88103
with pytest.warns(DeprecationWarning) as record:
89-
pagination.JsonApiLimitOffsetPagination()
104+
self.MyInheritedLimitOffsetPagination()
90105
assert len(record) == 1
91-
assert 'JsonApiLimitOffsetPagination' in str(record[0].message)
106+
assert 'LimitOffsetPagination is deprecated' in str(record[0].message)
107+
108+
with pytest.warns(None) as record:
109+
self.MyOverridenLimitOffsetPagination()
110+
assert len(record) == 0
92111

93112

94-
# TODO: This test fails under py27 but it's not clear why so just leave it out for now.
95-
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
96-
reason="python2.7 fails for unknown reason")
97113
class TestPageNumber:
98114
"""
99-
Unit tests for `pagination.JSONAPIPageNumberPagination`.
100-
TODO: add unit tests for changing query parameter names, limits, etc.
115+
Unit tests for `pagination.JsonApiPageNumberPagination`.
101116
"""
117+
118+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
119+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
102120
def test_page_number_deprecation(self):
103121
with pytest.warns(DeprecationWarning) as record:
104122
pagination.PageNumberPagination()
105123
assert len(record) == 1
106-
assert 'PageNumberPagination' in str(record[0].message)
124+
assert 'PageNumberPagination is deprecated' in str(record[0].message)
107125

126+
class MyInheritedPageNumberPagination(pagination.PageNumberPagination):
127+
"""
128+
Inherit the default values
129+
"""
130+
pass
131+
132+
class MyOverridenPageNumberPagination(pagination.PageNumberPagination):
133+
"""
134+
Explicitly set page_query_param and page_size_query_param to the "old" values.
135+
"""
136+
page_query_param = "page"
137+
page_size_query_param = "page_size"
138+
139+
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
140+
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
141+
def test_my_page_number_deprecation(self):
108142
with pytest.warns(DeprecationWarning) as record:
109-
pagination.JsonApiPageNumberPagination()
143+
self.MyInheritedPageNumberPagination()
110144
assert len(record) == 1
111-
assert 'JsonApiPageNumberPagination' in str(record[0].message)
145+
assert 'PageNumberPagination is deprecated' in str(record[0].message)
146+
147+
with pytest.warns(None) as record:
148+
self.MyOverridenPageNumberPagination()
149+
assert len(record) == 0

‎example/views.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_object(self):
3535
return super(BlogViewSet, self).get_object()
3636

3737

38-
class JSONAPIViewSet(ModelViewSet):
38+
class JsonApiViewSet(ModelViewSet):
3939
"""
4040
This is an example on how to configure DRF-jsonapi from
4141
within a class. It allows using DRF-jsonapi alongside
@@ -59,12 +59,12 @@ def handle_exception(self, exc):
5959
exc.status_code = HTTP_422_UNPROCESSABLE_ENTITY
6060
# exception handler can't be set on class so you have to
6161
# override the error response in this method
62-
response = super(JSONAPIViewSet, self).handle_exception(exc)
62+
response = super(JsonApiViewSet, self).handle_exception(exc)
6363
context = self.get_exception_handler_context()
6464
return format_drf_errors(response, context, exc)
6565

6666

67-
class BlogCustomViewSet(JSONAPIViewSet):
67+
class BlogCustomViewSet(JsonApiViewSet):
6868
queryset = Blog.objects.all()
6969
serializer_class = BlogSerializer
7070

‎rest_framework_json_api/pagination.py‎

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
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]'
@@ -50,11 +51,13 @@ def get_paginated_response(self, data):
5051
})
5152

5253

53-
class JSONAPILimitOffsetPagination(LimitOffsetPagination):
54+
class JsonApiLimitOffsetPagination(LimitOffsetPagination):
5455
"""
5556
A limit/offset based style. For example:
5657
http://api.example.org/accounts/?page[limit]=100
5758
http://api.example.org/accounts/?page[offset]=400&page[limit]=100
59+
60+
Use a private name for the implementation because the public name is pending deprecation.
5861
"""
5962
limit_query_param = 'page[limit]'
6063
offset_query_param = 'page[offset]'
@@ -100,63 +103,48 @@ def get_paginated_response(self, data):
100103
})
101104

102105

103-
class JsonApiPageNumberPagination(JSONAPIPageNumberPagination):
106+
class PageNumberPagination(JsonApiPageNumberPagination):
104107
"""
105-
Deprecated due to desire to use `JSONAPI` prefix for all classes.
108+
A soon-to-be-changed paginator that uses non-JSON:API query parameters (default:
109+
'page' and 'page_size' instead of 'page[number]' and 'page[size]').
106110
"""
107111
page_query_param = 'page'
108112
page_size_query_param = 'page_size'
109113

110114
def __init__(self):
111-
warnings.warn(
112-
'JsonApiPageNumberPagination is deprecated. Use JSONAPIPageNumberPagination '
113-
'or create custom pagination. See '
114-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
115-
DeprecationWarning)
116-
super(JsonApiPageNumberPagination, self).__init__()
117-
118-
119-
class PageNumberPagination(JSONAPIPageNumberPagination):
120-
"""
121-
Deprecated paginator that uses different query parameters
122-
"""
123-
page_query_param = 'page'
124-
page_size_query_param = 'page_size'
115+
if type(self) == PageNumberPagination:
116+
warn = self.page_query_param == 'page' or self.page_size_query_param == 'page_size'
117+
else: # inherited class doesn't override the attributes?
118+
warn = ('page_query_param' not in type(self).__dict__ or
119+
'page_size_query_param' not in type(self).__dict__)
120+
if warn:
121+
warnings.warn(
122+
'PageNumberPagination is deprecated use JsonApiPageNumberPagination instead. '
123+
'If you want to retain current defaults you will need to implement custom '
124+
'pagination class explicitly setting `page_query_param = "page"` and '
125+
'`page_size_query_param = "page_size"`. '
126+
'See changelog for more details.',
127+
DeprecationWarning)
125128

126-
def __init__(self):
127-
warnings.warn(
128-
'PageNumberPagination is deprecated. Use JSONAPIPageNumberPagination '
129-
'or create custom pagination. See '
130-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
131-
DeprecationWarning)
132129
super(PageNumberPagination, self).__init__()
133130

134131

135-
class JsonApiLimitOffsetPagination(JSONAPILimitOffsetPagination):
136-
"""
137-
Deprecated due to desire to use `JSONAPI` prefix for all classes.
138-
"""
139-
max_limit = None
140-
141-
def __init__(self):
142-
warnings.warn(
143-
'JsonApiLimitOffsetPagination is deprecated. Use JSONAPILimitOffsetPagination '
144-
'or create custom pagination. See '
145-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
146-
DeprecationWarning)
147-
super(JsonApiLimitOffsetPagination, self).__init__()
148-
149-
150-
class LimitOffsetPagination(JSONAPILimitOffsetPagination):
132+
class LimitOffsetPagination(JsonApiLimitOffsetPagination):
151133
"""
152134
Deprecated paginator that uses a different max_limit
153135
"""
154136
max_limit = None
155137

156138
def __init__(self):
157-
warnings.warn(
158-
'LimitOffsetPagination is deprecated. Use JSONAPILimitOffsetPagination '
159-
'or create custom pagination. See '
160-
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
161-
DeprecationWarning)
139+
if type(self) == LimitOffsetPagination:
140+
warn = self.max_limit is None
141+
else:
142+
warn = 'max_limit' not in type(self).__dict__
143+
if warn:
144+
warnings.warn(
145+
'LimitOffsetPagination is deprecated use JsonApiLimitOffsetPagination instead. '
146+
'If you want to retain current defaults you will need to implement custom '
147+
'pagination class explicitly setting `max_limit = None`. '
148+
'See changelog for more details.',
149+
DeprecationWarning)
162150
super(LimitOffsetPagination, self).__init__()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /