apipaginator.py 1.7 KB

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