apipaginator.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. from django.core.paginator import Paginator as DjangoPaginator, InvalidPage
  2. from django.utils import six
  3. from rest_framework.exceptions import NotFound
  4. from rest_framework.pagination import PageNumberPagination
  5. from rest_framework.response import Response
  6. from .shortcuts import pagination_dict
  7. class BaseApiPaginator(PageNumberPagination):
  8. def paginate_queryset(self, queryset, request, view=None):
  9. """
  10. Paginate a queryset if required, either returning a
  11. page object, or `None` if pagination is not configured for this view.
  12. """
  13. paginator = DjangoPaginator(
  14. queryset, self.page_size, orphans=self.page_orphans)
  15. page_number = request.query_params.get(self.page_query_param, 1)
  16. try:
  17. self.page = paginator.page(page_number)
  18. except InvalidPage as exc:
  19. msg = self.invalid_page_message.format(
  20. page_number=page_number, message=six.text_type(exc)
  21. )
  22. raise NotFound(msg)
  23. if paginator.count > 1 and self.template is not None:
  24. # The browsable API should display pagination controls.
  25. self.display_page_controls = True
  26. self.request = request
  27. return list(self.page)
  28. def get_meta(self):
  29. return pagination_dict(self.page)
  30. def get_paginated_response(self, data):
  31. response_data = self.get_meta()
  32. response_data['results'] = data
  33. return Response(response_data)
  34. def ApiPaginator(per_page=None, orphans=0):
  35. return type('ApiPaginator', (BaseApiPaginator, ), {
  36. 'page_size': per_page,
  37. 'page_orphans': orphans
  38. })