0
# Pagination
1
2
JSON:API compliant pagination classes that provide proper meta information and navigation links, supporting both page number and limit/offset pagination styles according to JSON:API specification.
3
4
## Capabilities
5
6
### JsonApiPageNumberPagination
7
8
Page number based pagination with JSON:API compliant query parameters and response format.
9
10
```python { .api }
11
class JsonApiPageNumberPagination(PageNumberPagination):
12
"""
13
JSON:API compliant page number pagination.
14
15
Uses JSON:API recommended query parameters:
16
- page[number]: Page number (1-based)
17
- page[size]: Items per page
18
19
Returns JSON:API compliant pagination metadata and links.
20
"""
21
22
page_query_param = "page[number]" # Query parameter for page number
23
page_size_query_param = "page[size]" # Query parameter for page size
24
max_page_size = 100 # Maximum allowed page size
25
26
def build_link(self, index):
27
"""
28
Build pagination link for given page index.
29
30
Args:
31
index: Page number (1-based) or None
32
33
Returns:
34
str or None: Full URL for the page
35
"""
36
37
def get_paginated_response(self, data):
38
"""
39
Generate JSON:API compliant paginated response.
40
41
Args:
42
data: Serialized page data
43
44
Returns:
45
Response: JSON:API response with data, meta, and links
46
"""
47
```
48
49
Usage example:
50
51
```python
52
# settings.py
53
REST_FRAMEWORK = {
54
'DEFAULT_PAGINATION_CLASS':
55
'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
56
'PAGE_SIZE': 20
57
}
58
59
# Or in view class:
60
from rest_framework_json_api.pagination import JsonApiPageNumberPagination
61
62
class ArticleViewSet(viewsets.ModelViewSet):
63
queryset = Article.objects.all()
64
pagination_class = JsonApiPageNumberPagination
65
66
# Request: GET /articles?page[number]=2&page[size]=10
67
# Response:
68
{
69
"data": [...],
70
"meta": {
71
"pagination": {
72
"page": 2,
73
"pages": 15,
74
"count": 150
75
}
76
},
77
"links": {
78
"first": "/articles?page[number]=1",
79
"prev": "/articles?page[number]=1",
80
"next": "/articles?page[number]=3",
81
"last": "/articles?page[number]=15"
82
}
83
}
84
```
85
86
### JsonApiLimitOffsetPagination
87
88
Limit/offset based pagination with JSON:API compliant query parameters.
89
90
```python { .api }
91
class JsonApiLimitOffsetPagination(LimitOffsetPagination):
92
"""
93
JSON:API compliant limit/offset pagination.
94
95
Uses JSON:API recommended query parameters:
96
- page[limit]: Number of items to return
97
- page[offset]: Number of items to skip
98
99
Returns JSON:API compliant pagination metadata and links.
100
"""
101
102
limit_query_param = "page[limit]" # Query parameter for limit
103
offset_query_param = "page[offset]" # Query parameter for offset
104
max_limit = 100 # Maximum allowed limit
105
106
def get_last_link(self):
107
"""
108
Generate link to last page.
109
110
Returns:
111
str or None: URL for last page
112
"""
113
114
def get_first_link(self):
115
"""
116
Generate link to first page.
117
118
Returns:
119
str or None: URL for first page
120
"""
121
122
def get_paginated_response(self, data):
123
"""
124
Generate JSON:API compliant paginated response.
125
126
Args:
127
data: Serialized page data
128
129
Returns:
130
Response: JSON:API response with data, meta, and links
131
"""
132
```
133
134
Usage example:
135
136
```python
137
from rest_framework_json_api.pagination import JsonApiLimitOffsetPagination
138
139
class ArticleViewSet(viewsets.ModelViewSet):
140
queryset = Article.objects.all()
141
pagination_class = JsonApiLimitOffsetPagination
142
143
# Request: GET /articles?page[limit]=10&page[offset]=20
144
# Response:
145
{
146
"data": [...],
147
"meta": {
148
"pagination": {
149
"count": 150,
150
"limit": 10,
151
"offset": 20
152
}
153
},
154
"links": {
155
"first": "/articles",
156
"prev": "/articles?page[limit]=10&page[offset]=10",
157
"next": "/articles?page[limit]=10&page[offset]=30",
158
"last": "/articles?page[limit]=10&page[offset]=140"
159
}
160
}
161
```
162
163
## Response Format
164
165
Both pagination classes generate JSON:API compliant responses with the following structure:
166
167
### Page Number Pagination Response
168
169
```python
170
{
171
"data": [
172
# Array of resource objects
173
],
174
"meta": {
175
"pagination": {
176
"page": 2, # Current page number (1-based)
177
"pages": 15, # Total number of pages
178
"count": 150 # Total number of items
179
}
180
},
181
"links": {
182
"first": "/articles?page[number]=1", # First page
183
"prev": "/articles?page[number]=1", # Previous page (null if first)
184
"next": "/articles?page[number]=3", # Next page (null if last)
185
"last": "/articles?page[number]=15" # Last page
186
}
187
}
188
```
189
190
### Limit/Offset Pagination Response
191
192
```python
193
{
194
"data": [
195
# Array of resource objects
196
],
197
"meta": {
198
"pagination": {
199
"count": 150, # Total number of items
200
"limit": 10, # Items per page
201
"offset": 20 # Number of items skipped
202
}
203
},
204
"links": {
205
"first": "/articles", # First page
206
"prev": "/articles?page[limit]=10&page[offset]=10", # Previous page
207
"next": "/articles?page[limit]=10&page[offset]=30", # Next page
208
"last": "/articles?page[limit]=10&page[offset]=140" # Last page
209
}
210
}
211
```
212
213
## Query Parameters
214
215
### Page Number Pagination
216
217
```python
218
# Basic pagination
219
GET /articles?page[number]=3
220
221
# With custom page size
222
GET /articles?page[number]=3&page[size]=25
223
224
# Combined with other parameters
225
GET /articles?page[number]=2&page[size]=10&include=author&sort=title
226
```
227
228
### Limit/Offset Pagination
229
230
```python
231
# Basic limit/offset
232
GET /articles?page[limit]=20&page[offset]=40
233
234
# Limit only (offset defaults to 0)
235
GET /articles?page[limit]=15
236
237
# Combined with other parameters
238
GET /articles?page[limit]=10&page[offset]=20&filter[published]=true
239
```
240
241
## Configuration
242
243
### Default Settings
244
245
```python
246
# settings.py
247
REST_FRAMEWORK = {
248
'DEFAULT_PAGINATION_CLASS':
249
'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
250
'PAGE_SIZE': 20
251
}
252
```
253
254
### Custom Pagination Classes
255
256
```python
257
from rest_framework_json_api.pagination import JsonApiPageNumberPagination
258
259
class CustomPagination(JsonApiPageNumberPagination):
260
page_size = 25
261
max_page_size = 50
262
263
def get_paginated_response(self, data):
264
response = super().get_paginated_response(data)
265
# Add custom meta information
266
response.data['meta']['custom'] = 'value'
267
return response
268
```
269
270
### Per-View Configuration
271
272
```python
273
class ArticleViewSet(viewsets.ModelViewSet):
274
queryset = Article.objects.all()
275
pagination_class = JsonApiLimitOffsetPagination
276
277
def get_paginated_response(self, data):
278
response = super().get_paginated_response(data)
279
# Add view-specific meta information
280
response.data['meta']['view'] = 'articles'
281
return response
282
```
283
284
## Empty Results
285
286
When no results are found:
287
288
```python
289
{
290
"data": [],
291
"meta": {
292
"pagination": {
293
"page": 1,
294
"pages": 0,
295
"count": 0
296
}
297
},
298
"links": {
299
"first": null,
300
"prev": null,
301
"next": null,
302
"last": null
303
}
304
}
305
```
306
307
## Error Handling
308
309
Invalid pagination parameters return appropriate errors:
310
311
```python
312
# Invalid page number
313
GET /articles?page[number]=invalid
314
315
# Response:
316
{
317
"errors": [{
318
"detail": "Invalid page number.",
319
"status": "400"
320
}]
321
}
322
323
# Page size too large
324
GET /articles?page[size]=500
325
326
# Response:
327
{
328
"errors": [{
329
"detail": "Page size too large. Maximum is 100.",
330
"status": "400"
331
}]
332
}
333
```
334
335
## Link Generation
336
337
Links preserve existing query parameters:
338
339
```python
340
# Request: GET /articles?include=author&sort=title&page[number]=2
341
# Links include the other parameters:
342
{
343
"links": {
344
"first": "/articles?include=author&sort=title&page[number]=1",
345
"next": "/articles?include=author&sort=title&page[number]=3",
346
# ...
347
}
348
}
349
```
350
351
## Types
352
353
```python { .api }
354
from rest_framework_json_api.pagination import (
355
JsonApiPageNumberPagination,
356
JsonApiLimitOffsetPagination
357
)
358
359
# Base classes from Django REST framework
360
from rest_framework.pagination import (
361
PageNumberPagination,
362
LimitOffsetPagination
363
)
364
```