Skip to content

Commit 4507ab9

Browse files
committed
Add configurable pagination query parameter names.
1 parent e501b04 commit 4507ab9

File tree

2 files changed

+70
-11
lines changed

2 files changed

+70
-11
lines changed

docs/usage.md

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,65 @@ REST_FRAMEWORK = {
3434
}
3535
```
3636

37-
If `PAGE_SIZE` is set the renderer will return a `meta` object with
37+
### Pagination settings
38+
39+
If `REST_FRAMEWORK['PAGE_SIZE']` is set the renderer will return a `meta` object with
3840
record count and a `links` object with the next, previous, first, and last links.
39-
Pages can be selected with the `page` GET parameter. The query parameter used to
40-
retrieve the page can be customized by subclassing `PageNumberPagination` and
41-
overriding the `page_query_param`. Page size can be controlled per request via
42-
the `PAGINATE_BY_PARAM` query parameter (`page_size` by default).
4341

44-
#### Performance Testing
42+
#### Subclassing paginators
43+
44+
The JSON API pagination classes can be subclassed to override settings as
45+
described in the [DRF pagination documentation](http://www.django-rest-framework.org/api-guide/pagination/).
46+
47+
The default values are shown in these examples:
48+
49+
```python
50+
from rest_framework_json_api.pagination import PageNumberPagination, LimitOffsetPagination
51+
52+
class MyPagePagination(PageNumberPagination):
53+
page_query_param = 'page'
54+
page_size_query_param = 'page_size'
55+
max_page_size = 100
56+
57+
class MyLimitPagination(LimitOffsetPagination):
58+
offset_query_param = 'page[offset]'
59+
limit_query_param = 'page[limit]'
60+
max_limit = None
61+
```
62+
63+
As shown above, pages can be selected with the `page` or `page[limit]` GET query parameter when using
64+
the PageNumberPagination or LimitOffsetPagination class, respectively.
65+
66+
If you want to use the PageNumberPagination query parameter names shown
67+
as an example in the JSON API [specification](http://jsonapi.org/format/#fetching-pagination),
68+
set them as follows:
69+
```python
70+
class MyPagePagination(PageNumberPagination):
71+
page_query_param = 'page[number]'
72+
page_size_query_param = 'page[size]'
73+
```
74+
75+
#### Setting global defaults for pagination
76+
77+
Set global defaults for the `PageNumberPagination` class with these settings:
78+
- `JSON_API_PAGE_NUMBER_PARAM` sets the name of the page number query parameter (default: "page").
79+
- `JSON_API_PAGE_SIZE_PARAM` sets the name of the page size query parameter (default: "page_size").
80+
- `JSON_API_MAX_PAGE_SIZE` sets an upper limit for the page size query parameter (default: 100).
81+
82+
Set global defaults for the `LimitOffsetPagination` class with these settings:
83+
- `JSON_API_PAGE_OFFSET_PARAM` sets the name of the page offset query parameter (default: "page\[offset\]").
84+
- `JSON_API_PAGE_LIMIT_PARAM` sets the name of the page limit query parameter (default: "page\[limit\]").
85+
- `JSON_API_MAX_PAGE_LIMIT` sets an upper limit for the page limit query parameter (default: None).
86+
87+
If you want to set the default PageNumberPagination query parameter names shown
88+
as an example in the JSON API [specification](http://jsonapi.org/format/#fetching-pagination),
89+
set them as follows:
90+
```python
91+
JSON_API_PAGE_NUMBER_PARAM = 'page[number]'
92+
JSON_API_PAGE_SIZE_PARAM = 'page[size]'
93+
```
94+
95+
### Performance Testing
4596

4697
If you are trying to see if your viewsets are configured properly to optimize performance,
4798
it is preferable to use `example.utils.BrowsableAPIRendererWithoutForms` instead of the default `BrowsableAPIRenderer`
@@ -606,6 +657,7 @@ with 1e18 rows which will likely exhaust any available memory and
606657
slow your database to crawl.
607658

608659
The prefetch_related case will issue 4 queries, but they will be small and fast queries.
660+
609661
<!--
610662
### Relationships
611663
### Errors

rest_framework_json_api/pagination.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
from collections import OrderedDict
55

6+
from django.conf import settings
67
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination
78
from rest_framework.utils.urls import remove_query_param, replace_query_param
89
from rest_framework.views import Response
@@ -11,10 +12,12 @@
1112
class PageNumberPagination(PageNumberPagination):
1213
"""
1314
A json-api compatible pagination format
15+
TODO: Consider changing defaults to page[number] and page[size].
16+
This would be a breaking change.
1417
"""
15-
16-
page_size_query_param = 'page_size'
17-
max_page_size = 100
18+
page_query_param = getattr(settings, 'JSON_API_PAGE_NUMBER_PARAM', 'page')
19+
page_size_query_param = getattr(settings, 'JSON_API_PAGE_SIZE_PARAM', 'page_size')
20+
max_page_size = getattr(settings, 'JSON_API_MAX_PAGE_SIZE', 100)
1821

1922
def build_link(self, index):
2023
if not index:
@@ -55,8 +58,10 @@ class LimitOffsetPagination(LimitOffsetPagination):
5558
http://api.example.org/accounts/?page[limit]=100
5659
http://api.example.org/accounts/?page[offset]=400&page[limit]=100
5760
"""
58-
limit_query_param = 'page[limit]'
59-
offset_query_param = 'page[offset]'
61+
limit_query_param = getattr(settings, 'JSON_API_PAGE_LIMIT_PARAM', 'page[limit]')
62+
offset_query_param = getattr(settings, 'JSON_API_PAGE_OFFSET_PARM', 'page[offset]')
63+
# TODO: inconsistent w/max_page_size value default of 100
64+
max_limit = getattr(settings, 'JSON_API_MAX_PAGE_LIMIT', None)
6065

6166
def get_last_link(self):
6267
if self.count == 0:
@@ -96,3 +101,5 @@ def get_paginated_response(self, data):
96101
('prev', self.get_previous_link())
97102
])
98103
})
104+
105+
# TODO: Add CursorPagination

0 commit comments

Comments
 (0)