pagination.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from django.conf import settings
  2. from django.db.models import QuerySet
  3. from rest_framework.pagination import LimitOffsetPagination
  4. class OptionalLimitOffsetPagination(LimitOffsetPagination):
  5. """
  6. Override the stock paginator to allow setting limit=0 to disable pagination for a request. This returns all objects
  7. matching a query, but retains the same format as a paginated request. The limit can only be disabled if
  8. MAX_PAGE_SIZE has been set to 0 or None.
  9. """
  10. def paginate_queryset(self, queryset, request, view=None):
  11. if isinstance(queryset, QuerySet):
  12. self.count = queryset.count()
  13. else:
  14. # We're dealing with an iterable, not a QuerySet
  15. self.count = len(queryset)
  16. self.limit = self.get_limit(request)
  17. self.offset = self.get_offset(request)
  18. self.request = request
  19. if self.limit and self.count > self.limit and self.template is not None:
  20. self.display_page_controls = True
  21. if self.count == 0 or self.offset > self.count:
  22. return list()
  23. if self.limit:
  24. return list(queryset[self.offset:self.offset + self.limit])
  25. else:
  26. return list(queryset[self.offset:])
  27. def get_limit(self, request):
  28. limit = super().get_limit(request)
  29. # Enforce maximum page size
  30. if settings.MAX_PAGE_SIZE:
  31. limit = min(limit, settings.MAX_PAGE_SIZE)
  32. return limit
  33. def get_next_link(self):
  34. # Pagination has been disabled
  35. if not self.limit:
  36. return None
  37. return super().get_next_link()
  38. def get_previous_link(self):
  39. # Pagination has been disabled
  40. if not self.limit:
  41. return None
  42. return super().get_previous_link()