mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-24 23:19:47 +03:00
Add test_ascending with nulls
This commit is contained in:
parent
e44d8de067
commit
a1866b329e
|
@ -633,8 +633,9 @@ class CursorPagination(BasePagination):
|
||||||
kwargs = {order_attr + '__gt': current_position}
|
kwargs = {order_attr + '__gt': current_position}
|
||||||
|
|
||||||
# If some records contain a null for the ordering field, don't lose them.
|
# If some records contain a null for the ordering field, don't lose them.
|
||||||
filter_query = Q(**kwargs) | Q(**{order_attr + '__isnull': True})
|
filter_query = Q(**kwargs)
|
||||||
|
if reverse:
|
||||||
|
filter_query |= Q(**{order_attr + '__isnull': True})
|
||||||
queryset = queryset.filter(filter_query)
|
queryset = queryset.filter(filter_query)
|
||||||
|
|
||||||
# If we have an offset cursor then offset the entire page by that amount.
|
# If we have an offset cursor then offset the entire page by that amount.
|
||||||
|
@ -708,7 +709,7 @@ class CursorPagination(BasePagination):
|
||||||
# The item in this position and the item following it
|
# The item in this position and the item following it
|
||||||
# have different positions. We can use this position as
|
# have different positions. We can use this position as
|
||||||
# our marker.
|
# our marker.
|
||||||
has_item_with_unique_position = True
|
has_item_with_unique_position = position is not None
|
||||||
break
|
break
|
||||||
|
|
||||||
# The item in this position has the same position as the item
|
# The item in this position has the same position as the item
|
||||||
|
@ -761,7 +762,7 @@ class CursorPagination(BasePagination):
|
||||||
# The item in this position and the item following it
|
# The item in this position and the item following it
|
||||||
# have different positions. We can use this position as
|
# have different positions. We can use this position as
|
||||||
# our marker.
|
# our marker.
|
||||||
has_item_with_unique_position = True
|
has_item_with_unique_position = position is not None
|
||||||
break
|
break
|
||||||
|
|
||||||
# The item in this position has the same position as the item
|
# The item in this position has the same position as the item
|
||||||
|
@ -887,7 +888,7 @@ class CursorPagination(BasePagination):
|
||||||
attr = instance[field_name]
|
attr = instance[field_name]
|
||||||
else:
|
else:
|
||||||
attr = getattr(instance, field_name)
|
attr = getattr(instance, field_name)
|
||||||
return str(attr)
|
return None if attr is None else str(attr)
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
return Response(OrderedDict([
|
return Response(OrderedDict([
|
||||||
|
|
|
@ -1084,6 +1084,78 @@ class TestCursorPaginationWithValueQueryset(CursorPaginationTestsMixin, TestCase
|
||||||
return (previous, current, next, previous_url, next_url)
|
return (previous, current, next, previous_url, next_url)
|
||||||
|
|
||||||
|
|
||||||
|
class NullableCursorPaginationModel(models.Model):
|
||||||
|
created = models.IntegerField(null=True)
|
||||||
|
|
||||||
|
|
||||||
|
class TestCursorPaginationWithNulls(TestCase):
|
||||||
|
"""
|
||||||
|
Unit tests for `pagination.CursorPagination` with ordering on a nullable field.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
class ExamplePagination(pagination.CursorPagination):
|
||||||
|
page_size = 1
|
||||||
|
ordering = 'created'
|
||||||
|
|
||||||
|
self.pagination = ExamplePagination()
|
||||||
|
data = [
|
||||||
|
None, None, 3, 4
|
||||||
|
]
|
||||||
|
for idx in data:
|
||||||
|
NullableCursorPaginationModel.objects.create(created=idx)
|
||||||
|
|
||||||
|
self.queryset = NullableCursorPaginationModel.objects.all()
|
||||||
|
|
||||||
|
get_pages = TestCursorPagination.get_pages
|
||||||
|
|
||||||
|
def test_ascending(self):
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages('/')
|
||||||
|
|
||||||
|
assert previous is None
|
||||||
|
assert current == [None]
|
||||||
|
assert next == [None]
|
||||||
|
assert previous_url is None
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(next_url)
|
||||||
|
|
||||||
|
assert previous == [None]
|
||||||
|
assert current == [None]
|
||||||
|
assert next == [3]
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(next_url)
|
||||||
|
|
||||||
|
assert previous == [3] # [None] paging artifact documented at https://github.com/ddelange/django-rest-framework/blob/3.14.0/rest_framework/pagination.py#L789
|
||||||
|
assert current == [3]
|
||||||
|
assert next == [4]
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(next_url)
|
||||||
|
|
||||||
|
assert previous == [3]
|
||||||
|
assert current == [4]
|
||||||
|
assert next is None
|
||||||
|
assert next_url is None
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(previous_url)
|
||||||
|
|
||||||
|
assert previous == [None]
|
||||||
|
assert current == [3]
|
||||||
|
assert next == [4]
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(previous_url)
|
||||||
|
|
||||||
|
assert previous == [None]
|
||||||
|
assert current == [None]
|
||||||
|
assert next == [None] # [3] paging artifact documented at https://github.com/ddelange/django-rest-framework/blob/3.14.0/rest_framework/pagination.py#L731
|
||||||
|
|
||||||
|
(previous, current, next, previous_url, next_url) = self.get_pages(previous_url)
|
||||||
|
|
||||||
|
assert previous is None
|
||||||
|
assert current == [None]
|
||||||
|
assert next == [None]
|
||||||
|
assert previous_url is None
|
||||||
|
|
||||||
|
|
||||||
def test_get_displayed_page_numbers():
|
def test_get_displayed_page_numbers():
|
||||||
"""
|
"""
|
||||||
Test our contextual page display function.
|
Test our contextual page display function.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user