From 37458db314ab6b0bc80a78d9295da291b1cd394c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Kervella?= Date: Thu, 24 May 2018 23:02:39 +0000 Subject: [PATCH] Add custom pagination for setting page_size --- api/pagination.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ api/settings.py | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 api/pagination.py diff --git a/api/pagination.py b/api/pagination.py new file mode 100644 index 00000000..a6a6adcb --- /dev/null +++ b/api/pagination.py @@ -0,0 +1,47 @@ +from rest_framework import pagination +from django.core import paginator +from django.utils.functional import cached_property + + +class AllowNegativePaginator(paginator.Paginator): + """ + Paginator subclass to allow negative or null `per_page` argument, + meaning to show all items in one page. + """ + def page(self, number): + """ + Bypass the default page creation to render all items if `per_page` + argument is negative or null. + """ + if self.per_page <= 0: + return self._get_page(self.object_list, 1, self) + return super(AllowNegativePaginator, self).page(number) + + @cached_property + def num_pages(self): + """ + Bypass the default number of page to return 1 if `per_page` argument + is negative or null. + """ + if self.per_page <= 0: + return 1 + return super(AllowNegativePaginator, self).num_pages + + +class PageSizedPagination(pagination.PageNumberPagination): + """ + Pagination subclass to all to control the page size + """ + page_size_query_param = 'page_size' + all_pages_strings = ('all',) + django_paginator_class = AllowNegativePaginator + + def get_page_size(self, request): + try: + page_size_str = request.query_params[self.page_size_query_param] + if page_size_str in self.all_pages_strings: + return -1 + except KeyError: + pass + + return super(PageSizedPagination, self).get_page_size(request) diff --git a/api/settings.py b/api/settings.py index 6bf48e33..c1ec4786 100644 --- a/api/settings.py +++ b/api/settings.py @@ -35,7 +35,7 @@ REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'api.permissions.DefaultACLPermission', ), - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'DEFAULT_PAGINATION_CLASS': 'api.pagination.PageSizedPagination', 'PAGE_SIZE': 100 }