Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7b29f36
initial integration of JSONAPIDjangoFilter
n2ygk Aug 23, 2018
dc5ca38
documentation, isort, flake8
n2ygk Aug 24, 2018
6b0dc8c
Forgot to add django_filters to installed_apps
n2ygk Aug 24, 2018
d4fbf24
backwards compatibility for py27 + django-filter
n2ygk Aug 24, 2018
d86d217
handle optional django-filter package
n2ygk Aug 24, 2018
83c4cc0
fix travis to match new TOXENVs due to django-filter
n2ygk Aug 24, 2018
f5792c1
fixed a typo
n2ygk Aug 24, 2018
cbc9d55
add a warning if django-filter is missing and JSONAPIDjangoFilter is …
n2ygk Aug 25, 2018
4f2b75b
improve filter_regex
n2ygk Aug 28, 2018
6a8d7ae
easy changes recommended by @sliverc review
n2ygk Aug 29, 2018
db9e1f9
resolve @sliverc review method of using optional django-filter.
n2ygk Aug 29, 2018
51b9946
rename JSONAPIDjangoFilter to DjangoFilterBackend.
n2ygk Aug 30, 2018
cfe89ea
Revert "deprecated JsonApi paginators class prefix to JSONAPI prefix …
n2ygk Aug 30, 2018
00dcf52
revert JSONAPI prefix from paginators
n2ygk Aug 30, 2018
fb17d78
override JSON_API_STANDARD_PAGINATION=False for test suite for now
n2ygk Aug 30, 2018
ee236ea
Merge branch 'master' into remove-JSONAPI-paginators
n2ygk Sep 6, 2018
6145d33
Revert "revert JSONAPI prefix from paginators"
n2ygk Sep 6, 2018
b90d983
Reverts JSONAPI prefix to JsonApi prefix on paginators
n2ygk Sep 7, 2018
5a8d67e
inadvertenly added a junked file
n2ygk Sep 7, 2018
7c8b044
PendingDeprecationWarnings
n2ygk Sep 8, 2018
929251f
Merge remote-tracking branch 'upstream/master' into remove-JSONAPI-pa…
Sep 12, 2018
1c810c0
Clarify deprecation warning of pagination classes
Sep 12, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
PendingDeprecationWarnings
- for renaming paginators without JsonApi prefix
- for changes to attribute defaults
  • Loading branch information
n2ygk committed Sep 8, 2018
commit 7c8b044bc27419e8f81ec23c631aec26f8392dc3
21 changes: 18 additions & 3 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ by setting `REST_FRAMEWORK['DEFAULT_PAGINATION_CLASS']` and by setting `REST_FRA
You can configure fixed values for the page size or limit -- or allow the client to choose the size or limit
via query parameters.

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

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

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

In release 3.0, the `JsonApi` prefix will be removed from the paginator names. If you currently use those (deprecated)
names (`PageNumberPagination` or `LimitOffsetPagination`) or would like to prepare now for this change, you will want to
explicitly override several of the class attributes.

To retain deprecated values for `PageNumberPagination` set `page_query_param = "page"` and
`page_size_query_param = "page_size"`.

To prepare for the renaming of `JsonApiPageNumberPagination` use `PageNumberPagination` now with
`page_query_param = "page[number]"` and `page_size_query_param = "page[size]"`.

To retain deprecated vales for `LimitOffsetPagination` set `max_limit = None`.

To prepare for the renaming of `JsonApiLimitOffsetPagination` to `LimitOffsetPagination` set `max_limit = 100`.

##### Examples
These examples show how to configure the parameters to use non-standard names and different limits:

```python
Expand Down
1 change: 0 additions & 1 deletion example/settings/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@

JSON_API_FORMAT_FIELD_NAMES = 'camelize'
JSON_API_FORMAT_TYPES = 'camelize'
JSON_API_STANDARD_PAGINATION = True
REST_FRAMEWORK = {
'PAGE_SIZE': 5,
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
Expand Down
2 changes: 0 additions & 2 deletions example/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
JSON_API_FIELD_NAMES = 'camelize'
JSON_API_FORMAT_TYPES = 'camelize'
JSON_API_PLURALIZE_TYPES = True
# TODO: 13 tests fail when this is True because they use `page` and `page_size`. Fix them.
JSON_API_STANDARD_PAGINATION = False

REST_FRAMEWORK.update({
'PAGE_SIZE': 1,
Expand Down
88 changes: 78 additions & 10 deletions example/tests/unit/test_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,95 @@ def test_valid_offset_limit(self):
@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_limit_offset_deprecation(self):
with pytest.warns(DeprecationWarning) as record:
with pytest.warns(PendingDeprecationWarning) as record:
pagination.LimitOffsetPagination()
assert len(record) == 2
assert len(record) == 1
assert 'LimitOffsetPagination will change in release 3.0' in str(record[0].message)
assert 'JsonApiLimitOffsetPagination will be replaced by LimitOffsetPagination' \
in str(record[1].message)

@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_jsonapi_limit_offset_deprecation(self):
with pytest.warns(PendingDeprecationWarning) as record:
pagination.JsonApiLimitOffsetPagination()
assert len(record) == 1
assert 'JsonApiLimitOffsetPagination will be renamed to LimitOffsetPagination'\
in str(record[0].message)

class MyInheritedLimitOffsetPagination(pagination.LimitOffsetPagination):
"""
Inherit the default values
"""
pass

class MyOverridenLimitOffsetPagination(pagination.LimitOffsetPagination):
"""
Explicitly set max_limit to the "old" values.
"""
max_limit = None

def test_my_limit_offset_deprecation(self):
with pytest.warns(PendingDeprecationWarning) as record:
self.MyInheritedLimitOffsetPagination()
assert len(record) == 1
assert 'LimitOffsetPagination will change in release 3.0' in str(record[0].message)

with pytest.warns(None) as record:
self.MyOverridenLimitOffsetPagination()
assert len(record) == 0


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

@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_page_number_deprecation(self):
with pytest.warns(DeprecationWarning) as record:
with pytest.warns(PendingDeprecationWarning) as record:
pagination.PageNumberPagination()
assert len(record) == 2
assert len(record) == 1
assert 'PageNumberPagination will change in release 3.0' in str(record[0].message)
assert 'JsonApiPageNumberPagination will be replaced by PageNumberPagination' \
in str(record[1].message)

@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_jsonapi_page_number_deprecation(self):
with pytest.warns(PendingDeprecationWarning) as record:
pagination.JsonApiPageNumberPagination()
assert len(record) == 1
assert 'JsonApiPageNumberPagination will be renamed to PageNumberPagination' \
in str(record[0].message)

class MyInheritedPageNumberPagination(pagination.PageNumberPagination):
"""
Inherit the default values
"""
pass

class MyOverridenPageNumberPagination(pagination.PageNumberPagination):
"""
Explicitly set page_query_param and page_size_query_param to the "old" values.
"""
page_query_param = "page"
page_size_query_param = "page_size"

@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_my_page_number_deprecation(self):
with pytest.warns(PendingDeprecationWarning) as record:
self.MyInheritedPageNumberPagination()
assert len(record) == 1
assert 'PageNumberPagination will change in release 3.0' in str(record[0].message)

with pytest.warns(None) as record:
self.MyOverridenPageNumberPagination()
assert len(record) == 0

@pytest.mark.xfail((sys.version_info.major, sys.version_info.minor) == (2, 7),
reason="python2.7 fails to generate DeprecationWarrning for unknown reason")
def test_my_jsonapi_page_number_deprecation(self):
with pytest.warns(PendingDeprecationWarning) as record:
pagination.JsonApiPageNumberPagination()
assert len(record) == 1
assert 'JsonApiPageNumberPagination will be renamed to PageNumberPagination' \
in str(record[0].message)
90 changes: 61 additions & 29 deletions rest_framework_json_api/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,15 @@
from rest_framework.views import Response


class JsonApiPageNumberPagination(PageNumberPagination):
class _JsonApiPageNumberPagination(PageNumberPagination):
"""
A json-api compatible pagination format
A json-api compatible pagination format.
Use a private name for the implementation because the public name is pending deprecation.
"""
page_query_param = 'page[number]'
page_size_query_param = 'page[size]'
max_page_size = 100

def __init__(self):
warnings.warn(
'JsonApiPageNumberPagination will be replaced by PageNumberPagination in release 3.0'
' See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
DeprecationWarning)
super(JsonApiPageNumberPagination, self).__init__()

def build_link(self, index):
if not index:
return None
Expand Down Expand Up @@ -58,24 +51,32 @@ def get_paginated_response(self, data):
})


class JsonApiLimitOffsetPagination(LimitOffsetPagination):
class JsonApiPageNumberPagination(_JsonApiPageNumberPagination):
"""
current public name to be deprecated soon.
"""
def __init__(self):
if type(self) == JsonApiPageNumberPagination:
warnings.warn(
'JsonApiPageNumberPagination will be renamed to PageNumberPagination in'
' release 3.0. See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
PendingDeprecationWarning)
super(_JsonApiPageNumberPagination, self).__init__()


class _JsonApiLimitOffsetPagination(LimitOffsetPagination):
"""
A limit/offset based style. For example:
http://api.example.org/accounts/?page[limit]=100
http://api.example.org/accounts/?page[offset]=400&page[limit]=100

Use a private name for the implementation because the public name is pending deprecation.
"""
limit_query_param = 'page[limit]'
offset_query_param = 'page[offset]'
max_limit = 100

def __init__(self):
warnings.warn(
'JsonApiLimitOffsetPagination will be replaced by LimitOffsetPagination in release 3.0'
' See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
DeprecationWarning)
super(JsonApiLimitOffsetPagination, self).__init__()

def get_last_link(self):
if self.count == 0:
return None
Expand Down Expand Up @@ -116,34 +117,65 @@ def get_paginated_response(self, data):
})


class PageNumberPagination(JsonApiPageNumberPagination):
class JsonApiLimitOffsetPagination(_JsonApiLimitOffsetPagination):
"""
current public name to be deprecated soon.
"""

def __init__(self):
warnings.warn(
'JsonApiLimitOffsetPagination will be renamed to LimitOffsetPagination in release 3.0'
' See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination',
PendingDeprecationWarning)
super(JsonApiLimitOffsetPagination, self).__init__()



class PageNumberPagination(_JsonApiPageNumberPagination):
"""
Deprecated paginator that uses different query parameters
A soon-to-be-changed paginator that uses non-JSON:API query parameters (default:
'page' and 'page_size' instead of 'page[number]' and 'page[size]').
"""
page_query_param = 'page'
page_size_query_param = 'page_size'

def __init__(self):
if self.page_query_param == 'page' or self.page_size_query_param == 'page_size':
if type(self) == PageNumberPagination:
warn = self.page_query_param == 'page' or self.page_size_query_param == 'page_size'
else: # inherited class doesn't override the attributes?
warn = ('page_query_param' not in type(self).__dict__ or
'page_size_query_param' not in type(self).__dict__)
if warn:
warnings.warn(
'PageNumberPagination will change in release 3.0 to default to use page[number] and'
' page[size] query parameters. See '
'PageNumberPagination will change in release 3.0 to change default values to: '
'`page_query_param = "page[number]"` and `page_size_query_param = "page[size]"`. '
'If you want to retain the current defaults you will need to explicitly set '
'`page_query_param = "page"` and `page_size_query_param = "page_size"`. '
'See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
DeprecationWarning)
PendingDeprecationWarning)

super(PageNumberPagination, self).__init__()


class LimitOffsetPagination(JsonApiLimitOffsetPagination):
class LimitOffsetPagination(_JsonApiLimitOffsetPagination):
"""
Deprecated paginator that uses a different max_limit
"""
max_limit = None

def __init__(self):
if self.max_limit is None:
if type(self) == LimitOffsetPagination:
warn = self.max_limit is None
else:
warn = 'max_limit' not in type(self).__dict__
if warn:
warnings.warn(
'LimitOffsetPagination will change in release 3.0 to default to max_limit=100. '
'LimitOffsetPagination will change in release 3.0 to default to `max_limit=100`. '
'If you want to retain the current default you will need to explicitly set '
'`max_limit = None`.'
'See '
'https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#pagination', # noqa: E501
DeprecationWarning)
PendingDeprecationWarning)
super(LimitOffsetPagination, self).__init__()