forked from django-json-api/django-rest-framework-json-api
- Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpagination.py
98 lines (81 loc) · 3.02 KB
/
pagination.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
Pagination fields
"""
fromcollectionsimportOrderedDict
fromrest_frameworkimportserializers
fromrest_framework.viewsimportResponse
fromrest_framework.paginationimportPageNumberPagination, LimitOffsetPagination
fromrest_framework.utils.urlsimportremove_query_param, replace_query_param
classPageNumberPagination(PageNumberPagination):
"""
A json-api compatible pagination format
"""
page_size_query_param='page_size'
max_page_size=100
defbuild_link(self, index):
ifnotindex:
returnNone
url=self.requestandself.request.build_absolute_uri() or''
returnreplace_query_param(url, self.page_query_param, index)
defget_paginated_response(self, data):
next=None
previous=None
ifself.page.has_next():
next=self.page.next_page_number()
ifself.page.has_previous():
previous=self.page.previous_page_number()
returnResponse({
'results': data,
'meta': {
'pagination': OrderedDict([
('page', self.page.number),
('pages', self.page.paginator.num_pages),
('count', self.page.paginator.count),
])
},
'links': OrderedDict([
('first', self.build_link(1)),
('last', self.build_link(self.page.paginator.num_pages)),
('next', self.build_link(next)),
('prev', self.build_link(previous))
])
})
classLimitOffsetPagination(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
"""
limit_query_param='page[limit]'
offset_query_param='page[offset]'
defget_last_link(self):
ifself.count==0:
returnNone
url=self.request.build_absolute_uri()
url=replace_query_param(url, self.limit_query_param, self.limit)
offset=self.count-self.limit
ifoffset<=0:
returnremove_query_param(url, self.offset_query_param)
returnreplace_query_param(url, self.offset_query_param, offset)
defget_first_link(self):
ifself.count==0:
returnNone
url=self.request.build_absolute_uri()
returnremove_query_param(url, self.offset_query_param)
defget_paginated_response(self, data):
returnResponse({
'results': data,
'meta': {
'pagination': OrderedDict([
('count', self.count),
('limit', self.limit),
('offset', self.offset),
])
},
'links': OrderedDict([
('first', self.get_first_link()),
('last', self.get_last_link()),
('next', self.get_next_link()),
('prev', self.get_previous_link())
])
})