Skip to content

Commit 4911f49

Browse files
committed
Introduce CursorPagination
1 parent 572852d commit 4911f49

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

styleguide_example/api/pagination.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from collections import OrderedDict
2+
from urllib.parse import parse_qs, urlparse
23

34
from rest_framework.pagination import LimitOffsetPagination as _LimitOffsetPagination
5+
from rest_framework.pagination import CursorPagination as _CursorPagination
46
from rest_framework.response import Response
57

68

@@ -45,3 +47,48 @@ def get_paginated_response(self, data):
4547
('previous', self.get_previous_link()),
4648
('results', data)
4749
]))
50+
51+
52+
class CursorPagination(_CursorPagination):
53+
page_size = 50 # Return 50 items by default
54+
55+
def __init__(self, ordering):
56+
self.ordering: str = ordering or "-created_at"
57+
58+
def get_ordering(self, request, queryset, view):
59+
# The DRF CursorPagination expects the ordering as a tuple
60+
if isinstance(self.ordering, str):
61+
return (self.ordering,)
62+
63+
return tuple(self.ordering)
64+
65+
def _get_cursor(self, url):
66+
if not url:
67+
return None
68+
69+
parsed_params = parse_qs(urlparse(url).query)
70+
# `parse_qs` values are lists
71+
cursor_params = parsed_params.get("cursor", [])
72+
if not cursor_params:
73+
return None
74+
75+
return cursor_params[0]
76+
77+
def get_paginated_response(self, data):
78+
next_url = self.get_next_link()
79+
next_cursor = self._get_cursor(next_url)
80+
81+
previous_url = self.get_previous_link()
82+
previous_cursor = self._get_cursor(previous_url)
83+
84+
return Response(
85+
OrderedDict(
86+
[
87+
("next", next_url),
88+
("next_cursor", next_cursor),
89+
("previous", previous_url),
90+
("previous_cursor", previous_cursor),
91+
("results", data),
92+
]
93+
)
94+
)

0 commit comments

Comments
 (0)