How to paginate response from function based view of django rest framework?
http://www.django-rest-framework.org/api-guide/pagination/
from rest_framework.pagination import PageNumberPagination
@api_view(['GET',])
@permission_classes([AllowAny,])
def PersonView(request):
paginator = PageNumberPagination()
paginator.page_size = 10
person_objects = Person.objects.all()
result_page = paginator.paginate_queryset(person_objects, request)
serializer = PersonSerializer(result_page, many=True)
return paginator.get_paginated_response(serializer.data)
You can also define custom pagination class by overriding PageNumberPagination
pagination.py
from rest_framework import pagination
class StandardResultsSetPagination(pagination.PageNumberPagination):
page_size = 10
page_query_param = 'page'
page_size_query_param = 'per_page'
max_page_size = 1000
it will help to define
page_size, page query custom parameters and max_page_size
views.py
from rest_api.pagination import StandardResultsSetPagination
@api_view(['GET',])
@permission_classes([AllowAny,])
def PersonView(request):
person_objects = Person.objects.all()
if len(person_objects)> 0:
paginator = StandardResultsSetPagination()
result_page = paginator.paginate_queryset(person_objects, request)
serializer = PersonSerializer(result_page, many=True)
return paginator.get_paginated_response(serializer.data)
else:
return Response({},status=status.HTTP_200_OK)
Eg: Request
GET https://api.example.org/persons/?page=1&per_page=10
Response
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/persons/?page=2&per_page=10",
"previous": null,
"results": [
…
]
}
The ACCEPTED answer has a BUG
A ModelSerializer accepts a queryset or an object, in the accepted answer the PersonSerializer
is given the ouput of paginator.paginate_queryset
which returns a list containing single element of class Page and thus the serializer will either return incomplete data or no data at all(know this because have tried and seen wrong results).
This can be easily fixed by passing the actual queryset to the serializer which in this case will be person_objects
,
So the final code will be,
from rest_framework.pagination import PageNumberPagination
@api_view(['GET',])
@permission_classes([AllowAny,])
def PersonView(request):
paginator = PageNumberPagination()
paginator.page_size = 10
person_objects = Person.objects.all()
result_page = paginator.paginate_queryset(person_objects, request)
serializer = PersonSerializer(person_objects, many=True) # MAIN CHANGE IS HERE
return paginator.get_paginated_response(serializer.data)
This fixes the bug but passing the complete queryset to serializer will take lot of time for serializing since serializer works on lazy approach, but this performance issue is in itself a new question.