|
@@ -5,6 +5,7 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
|
|
|
from rest_framework import authentication, exceptions
|
|
|
from rest_framework.exceptions import APIException
|
|
|
+from rest_framework.pagination import LimitOffsetPagination
|
|
|
from rest_framework.permissions import DjangoModelPermissions, SAFE_METHODS
|
|
|
from rest_framework.serializers import Field, ValidationError
|
|
|
|
|
@@ -105,3 +106,51 @@ class WritableSerializerMixin(object):
|
|
|
if self.action in WRITE_OPERATIONS and hasattr(self, 'write_serializer_class'):
|
|
|
return self.write_serializer_class
|
|
|
return self.serializer_class
|
|
|
+
|
|
|
+
|
|
|
+class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
|
|
+ """
|
|
|
+ Override the stock paginator to allow setting limit=0 to disable pagination for a request. This returns all objects
|
|
|
+ matching a query, but retains the same format as a paginated request. The limit can only be disabled if
|
|
|
+ MAX_PAGE_SIZE has been set to 0 or None.
|
|
|
+ """
|
|
|
+
|
|
|
+ def paginate_queryset(self, queryset, request, view=None):
|
|
|
+
|
|
|
+ try:
|
|
|
+ self.count = queryset.count()
|
|
|
+ except (AttributeError, TypeError):
|
|
|
+ self.count = len(queryset)
|
|
|
+ self.limit = self.get_limit(request)
|
|
|
+ self.offset = self.get_offset(request)
|
|
|
+ self.request = request
|
|
|
+
|
|
|
+ if self.limit and self.count > self.limit and self.template is not None:
|
|
|
+ self.display_page_controls = True
|
|
|
+
|
|
|
+ if self.count == 0 or self.offset > self.count:
|
|
|
+ return list()
|
|
|
+
|
|
|
+ if self.limit:
|
|
|
+ return list(queryset[self.offset:self.offset + self.limit])
|
|
|
+ else:
|
|
|
+ return list(queryset[self.offset:])
|
|
|
+
|
|
|
+ def get_limit(self, request):
|
|
|
+
|
|
|
+ if self.limit_query_param:
|
|
|
+ try:
|
|
|
+ limit = int(request.query_params[self.limit_query_param])
|
|
|
+ if limit < 0:
|
|
|
+ raise ValueError()
|
|
|
+ # Enforce maximum page size, if defined
|
|
|
+ if settings.MAX_PAGE_SIZE:
|
|
|
+ if limit == 0:
|
|
|
+ return settings.MAX_PAGE_SIZE
|
|
|
+ else:
|
|
|
+ return min(limit, settings.MAX_PAGE_SIZE)
|
|
|
+ return limit
|
|
|
+ except (KeyError, ValueError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ return self.default_limit
|