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`.)
This commit is contained in:
Tom Christie 2013-08-28 12:52:38 +01:00
parent e1b54f2a2a
commit 4c53fb883f
2 changed files with 14 additions and 17 deletions

View File

@ -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,21 +208,15 @@ 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
return self.paginate_by
def get_serializer_class(self):
"""

View File

@ -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()