diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 97f44e673..183c34552 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -190,6 +190,25 @@ class DestroyModelMixin(object): return Response(status=status.HTTP_204_NO_CONTENT) +class OffsetLimitPaginationMixin(object): + offset_kwarg = 'offset' + paginate_by_param = 'limit' + pagination_serializer_class = pagination.OffsetLimitPaginationSerializer + + def paginate_queryset(self, queryset): + limit = self.get_paginate_by() + if not limit: + return # pagination not configured + offset_kwarg = self.kwargs.get(self.offset_kwarg) + offset_query_param = self.request.QUERY_PARAMS.get(self.offset_kwarg) + offset = offset_kwarg or offset_query_param or 0 + try: + offset_number = pagination.strict_positive_int(offset) + except ValueError: + offset_number = 0 + return pagination.OffsetLimitPage(queryset, offset_number, limit) + + class LinkPaginationMixin(object): pagination_serializer_class = pagination.LinkPaginationSerializer diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index 2e03e5961..d2d384d8d 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -150,3 +150,17 @@ class LinkPaginationSerializer(PaginationSerializer): if (rel in self.relations and link is not None) ] return {'Link': ', '.join(link_keader_items)} + + +class OffsetLimitPage(object): + """ + A base class to allow offset and limit when listing a queryset. + """ + def __init__(self, queryset, offset, limit): + self.count = queryset.count() + self.object_list = queryset[offset:offset + limit] + + +class OffsetLimitPaginationSerializer(BasePaginationSerializer): + """ OffsetLimitPage serializer """ + count = serializers.Field()