mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 00:04:16 +03:00
Cleaning up cursor implementation
This commit is contained in:
parent
4919492582
commit
492f3c410d
|
@ -381,10 +381,33 @@ class LimitOffsetPagination(BasePagination):
|
||||||
return template.render(context)
|
return template.render(context)
|
||||||
|
|
||||||
|
|
||||||
|
Cursor = namedtuple('Cursor', ['offset', 'reverse', 'position'])
|
||||||
|
|
||||||
|
|
||||||
|
def decode_cursor(encoded):
|
||||||
|
tokens = urlparse.parse_qs(b64decode(encoded))
|
||||||
|
try:
|
||||||
|
offset = int(tokens['offset'][0])
|
||||||
|
reverse = bool(int(tokens['reverse'][0]))
|
||||||
|
position = tokens['position'][0]
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return Cursor(offset=offset, reverse=reverse, position=position)
|
||||||
|
|
||||||
|
|
||||||
|
def encode_cursor(cursor):
|
||||||
|
tokens = {
|
||||||
|
'offset': str(cursor.offset),
|
||||||
|
'reverse': '1' if cursor.reverse else '0',
|
||||||
|
'position': cursor.position
|
||||||
|
}
|
||||||
|
return b64encode(urlparse.urlencode(tokens, doseq=True))
|
||||||
|
|
||||||
|
|
||||||
class CursorPagination(BasePagination):
|
class CursorPagination(BasePagination):
|
||||||
# reverse
|
# reverse
|
||||||
# limit
|
# limit
|
||||||
# multiple orderings
|
|
||||||
cursor_query_param = 'cursor'
|
cursor_query_param = 'cursor'
|
||||||
page_size = 5
|
page_size = 5
|
||||||
|
|
||||||
|
@ -396,10 +419,11 @@ class CursorPagination(BasePagination):
|
||||||
if encoded is None:
|
if encoded is None:
|
||||||
cursor = None
|
cursor = None
|
||||||
else:
|
else:
|
||||||
cursor = self.decode_cursor(encoded, self.ordering)
|
cursor = decode_cursor(encoded)
|
||||||
|
# TODO: Invalid cursors should 404
|
||||||
|
|
||||||
if cursor is not None:
|
if cursor is not None:
|
||||||
kwargs = {self.ordering + '__gt': cursor}
|
kwargs = {self.ordering + '__gt': cursor.position}
|
||||||
queryset = queryset.filter(**kwargs)
|
queryset = queryset.filter(**kwargs)
|
||||||
|
|
||||||
results = list(queryset[:self.page_size + 1])
|
results = list(queryset[:self.page_size + 1])
|
||||||
|
@ -411,20 +435,21 @@ class CursorPagination(BasePagination):
|
||||||
if not self.has_next:
|
if not self.has_next:
|
||||||
return None
|
return None
|
||||||
last_item = self.page[-1]
|
last_item = self.page[-1]
|
||||||
cursor = self.get_cursor_from_instance(last_item, self.ordering)
|
position = self.get_position_from_instance(last_item, self.ordering)
|
||||||
encoded = self.encode_cursor(cursor, self.ordering)
|
cursor = Cursor(offset=0, reverse=False, position=position)
|
||||||
|
encoded = encode_cursor(cursor)
|
||||||
return replace_query_param(self.base_url, self.cursor_query_param, encoded)
|
return replace_query_param(self.base_url, self.cursor_query_param, encoded)
|
||||||
|
|
||||||
def get_ordering(self):
|
def get_ordering(self):
|
||||||
return 'created'
|
return 'created'
|
||||||
|
|
||||||
def get_cursor_from_instance(self, instance, ordering):
|
def get_position_from_instance(self, instance, ordering):
|
||||||
return getattr(instance, ordering)
|
return str(getattr(instance, ordering))
|
||||||
|
|
||||||
def decode_cursor(self, encoded, ordering):
|
# def decode_cursor(self, encoded, ordering):
|
||||||
items = urlparse.parse_qs(b64decode(encoded))
|
# items = urlparse.parse_qs(b64decode(encoded))
|
||||||
return items.get(ordering)[0]
|
# return items.get(ordering)[0]
|
||||||
|
|
||||||
def encode_cursor(self, cursor, ordering):
|
# def encode_cursor(self, cursor, ordering):
|
||||||
items = [(ordering, cursor)]
|
# items = [(ordering, cursor)]
|
||||||
return b64encode(urlparse.urlencode(items, doseq=True))
|
# return b64encode(urlparse.urlencode(items, doseq=True))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user