mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-08 06:14:47 +03:00
Fixed admin pagination when limit is 0.
This commit is contained in:
parent
22695ec8a7
commit
c5425ac39d
|
@ -313,13 +313,22 @@ class LimitOffsetPagination(BasePagination):
|
||||||
('results', data)
|
('results', data)
|
||||||
]))
|
]))
|
||||||
|
|
||||||
|
def get_zero_limit(self):
|
||||||
|
# By default we return max_limit, but one could also return default_limit.
|
||||||
|
return self.max_limit
|
||||||
|
|
||||||
def get_limit(self, request):
|
def get_limit(self, request):
|
||||||
if self.limit_query_param:
|
if self.limit_query_param:
|
||||||
try:
|
try:
|
||||||
return _positive_int(
|
limit = _positive_int(
|
||||||
request.query_params[self.limit_query_param],
|
request.query_params[self.limit_query_param],
|
||||||
cutoff=self.max_limit
|
cutoff=self.max_limit
|
||||||
)
|
)
|
||||||
|
# User can specify limit == 0 to specify max (and not default) limit.
|
||||||
|
# By default (max_limit is None) this disables pagination.
|
||||||
|
if limit == 0:
|
||||||
|
limit = self.get_zero_limit()
|
||||||
|
return limit
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -357,7 +366,23 @@ class LimitOffsetPagination(BasePagination):
|
||||||
return replace_query_param(url, self.offset_query_param, offset)
|
return replace_query_param(url, self.offset_query_param, offset)
|
||||||
|
|
||||||
def get_html_context(self):
|
def get_html_context(self):
|
||||||
|
# paginate_queryset should be called before, to set
|
||||||
|
# self.limit and other values on self.
|
||||||
|
|
||||||
|
if self.limit is None:
|
||||||
|
return {
|
||||||
|
'previous_url': None,
|
||||||
|
'next_url': None,
|
||||||
|
'page_links': []
|
||||||
|
}
|
||||||
|
|
||||||
base_url = self.request.build_absolute_uri()
|
base_url = self.request.build_absolute_uri()
|
||||||
|
|
||||||
|
# This changes the URL in fact only when limit is 0 (which makes limit == max_limit)
|
||||||
|
# or when limit is missing (which makes it default_limit). We want to inform
|
||||||
|
# the user what this effective limit is.
|
||||||
|
base_url = replace_query_param(base_url, self.limit_query_param, self.limit)
|
||||||
|
|
||||||
current = _divide_with_ceil(self.offset, self.limit) + 1
|
current = _divide_with_ceil(self.offset, self.limit) + 1
|
||||||
# The number of pages is a little bit fiddly.
|
# The number of pages is a little bit fiddly.
|
||||||
# We need to sum both the number of pages from current offset to end
|
# We need to sum both the number of pages from current offset to end
|
||||||
|
|
|
@ -322,7 +322,10 @@ class TestLimitOffset:
|
||||||
self.queryset = range(1, 101)
|
self.queryset = range(1, 101)
|
||||||
|
|
||||||
def paginate_queryset(self, request):
|
def paginate_queryset(self, request):
|
||||||
return list(self.pagination.paginate_queryset(self.queryset, request))
|
queryset = self.pagination.paginate_queryset(self.queryset, request)
|
||||||
|
if queryset is None:
|
||||||
|
return None
|
||||||
|
return list(queryset)
|
||||||
|
|
||||||
def get_paginated_content(self, queryset):
|
def get_paginated_content(self, queryset):
|
||||||
response = self.pagination.get_paginated_response(queryset)
|
response = self.pagination.get_paginated_response(queryset)
|
||||||
|
@ -505,6 +508,52 @@ class TestLimitOffset:
|
||||||
assert content.get('next') == next_url
|
assert content.get('next') == next_url
|
||||||
assert content.get('previous') == prev_url
|
assert content.get('previous') == prev_url
|
||||||
|
|
||||||
|
def test_limit_is_zero(self):
|
||||||
|
"""
|
||||||
|
A limit of zero should set limit to max_limit.
|
||||||
|
"""
|
||||||
|
offset = 20
|
||||||
|
request = Request(factory.get('/', {'limit': 0, 'offset': offset}))
|
||||||
|
queryset = self.paginate_queryset(request)
|
||||||
|
content = self.get_paginated_content(queryset)
|
||||||
|
context = self.get_html_context()
|
||||||
|
assert queryset == self.queryset[20:35]
|
||||||
|
assert content == {
|
||||||
|
'results': self.queryset[20:35],
|
||||||
|
'previous': 'http://testserver/?limit=15&offset=5',
|
||||||
|
'next': 'http://testserver/?limit=15&offset=35',
|
||||||
|
'count': 100
|
||||||
|
}
|
||||||
|
assert context == {
|
||||||
|
'previous_url': 'http://testserver/?limit=15&offset=5',
|
||||||
|
'next_url': 'http://testserver/?limit=15&offset=35',
|
||||||
|
'page_links': [
|
||||||
|
PageLink('http://testserver/?limit=15', 1, False, False),
|
||||||
|
PageLink('http://testserver/?limit=15&offset=5', 2, False, False),
|
||||||
|
PageLink('http://testserver/?limit=15&offset=20', 3, True, False),
|
||||||
|
PageLink('http://testserver/?limit=15&offset=35', 4, False, False),
|
||||||
|
PAGE_BREAK,
|
||||||
|
PageLink('http://testserver/?limit=15&offset=95', 8, False, False),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_limit_is_zero_with_no_limit(self):
|
||||||
|
"""
|
||||||
|
A limit of zero should set limit to max_limit, but when it is None,
|
||||||
|
pagination should be disabled and whole queryset returned.
|
||||||
|
"""
|
||||||
|
self.pagination.max_limit = None
|
||||||
|
offset = 30
|
||||||
|
request = Request(factory.get('/', {'limit': 0, 'offset': offset}))
|
||||||
|
queryset = self.paginate_queryset(request)
|
||||||
|
context = self.get_html_context()
|
||||||
|
assert queryset is None
|
||||||
|
assert context == {
|
||||||
|
'previous_url': None,
|
||||||
|
'next_url': None,
|
||||||
|
'page_links': []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestCursorPagination:
|
class TestCursorPagination:
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user