Commit 4c53fb88 by Tom Christie

Tweak MAX_PAGINATE_BY behavior in edge case.

Always respect `paginate_by` settings if client does not specify page
size.  (Even if the developer has misconfigured, so that `paginate_by >
max`.)
parent e1b54f2a
......@@ -14,13 +14,15 @@ from rest_framework.settings import api_settings
import warnings
def strict_positive_int(integer_string):
def strict_positive_int(integer_string, cutoff=None):
"""
Cast a string to a strictly positive integer.
"""
ret = int(integer_string)
if ret <= 0:
raise ValueError()
if cutoff:
ret = min(ret, cutoff)
return ret
def get_object_or_404(queryset, **filter_kwargs):
......@@ -206,20 +208,14 @@ class GenericAPIView(views.APIView):
PendingDeprecationWarning, stacklevel=2)
if self.paginate_by_param:
query_params = self.request.QUERY_PARAMS
try:
paginate_by_param = int(query_params[self.paginate_by_param])
return strict_positive_int(
self.request.QUERY_PARAMS[self.paginate_by_param],
cutoff=self.max_paginate_by
)
except (KeyError, ValueError):
pass
else:
if self.max_paginate_by is not None:
return min(self.max_paginate_by, paginate_by_param)
else:
return paginate_by_param
if self.max_paginate_by:
return min(self.max_paginate_by, self.paginate_by)
else:
return self.paginate_by
def get_serializer_class(self):
......
......@@ -47,8 +47,8 @@ class MaxPaginateByView(generics.ListAPIView):
View for testing custom max_paginate_by usage
"""
model = BasicModel
paginate_by = 5
max_paginate_by = 3
paginate_by = 3
max_paginate_by = 5
paginate_by_param = 'page_size'
......@@ -343,16 +343,17 @@ class TestMaxPaginateByParam(TestCase):
def test_max_paginate_by(self):
"""
If max_paginate_by is set and it less than paginate_by, new kwarg should limit requests for review.
If max_paginate_by is set, it should limit page size for the view.
"""
request = factory.get('/?page_size=10')
response = self.view(request).render()
self.assertEqual(response.data['count'], 13)
self.assertEqual(response.data['results'], self.data[:3])
self.assertEqual(response.data['results'], self.data[:5])
def test_max_paginate_by_without_page_size_param(self):
"""
If max_paginate_by is set, new kwarg should limit requests for review.
If max_paginate_by is set, but client does not specifiy page_size,
standard `paginate_by` behavior should be used.
"""
request = factory.get('/')
response = self.view(request).render()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment