My pagination Class
class ArticleListPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
My Article View Class
class Article(generics.GenericAPIView):
queryset = Articles.objects.all()
serializer_class = ArticlesSerializer
pagination_class = ArticleListPagination
def get(self, request):
queryset = self.get_queryset()
serializer = ArticlesSerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
I am able to use custom pagination class using this
def get(self, request):
queryset = self.get_queryset()
page = ArticleListPagination()
new = page.paginate_queryset(queryset, request)
serializer = ArticlesSerializer(new, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
Is it the proper way to use ArticleListPagination
? If I have stated in my class that my pagination class is ArticleListPagination
, why it is not changing the return queryset object.
for django_rest_framework 3.0.x (or below):
You can extends the rest_framework.mixins.ListModelMixin
directly, or you imlement the get
or list
method similar to that.
Of course generics.GenericAPIView
is also needed.
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
# get_paginaion_serializer will read your DEFAULT_PAGINATION_SERIALIZER_CLASS
# or view.pagination_serializer_class
# we will talk the two variable later
serializer = self.get_pagination_serializer(page)
else:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
if you wanna config it "global", you can config in your settings.py
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'YourCustomPaginationSerializer',
# ...
}
if you just wanna set to the specific view:
the attribute is pagination_serializer_class
instead of pagination_class
.
class MyView(generics.GenericAPIView):
pagination_serializer_class = YourCustomPaginationSerializerClass
for django_rest_framework 3.1.x:
it's a slightly different, you can check the docs first. 3.1 Announcement , Pagination Docs
You can extends the rest_framework.mixins.ListModelMixin
directly, or you imlement the get
method similar to that.
Of course generics.GenericAPIView
is also needed.
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
if you wanna config it "global", you can config in your settings.py
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
# ...
}
if you just wanna set to the specific view:
class MyView(generics.GenericAPIView):
pagination_class = YourCustomPaginationClass
You can use your custom pagination in viewset and changed on custom view
pagination.py
class OneByOneItems(pagination.PageNumberPagination):
page_size = 2
def get_paginated_response(self, data):
return Response(OrderedDict([
('lastPage', self.page.paginator.count),
('countItemsOnPage', self.page_size),
('current', self.page.number),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
views.py
class LectionViewSet(viewsets.ReadOnlyModelViewSet):
queryset = LectionCourse.objects.all().order_by('-created_at')
serializer_class = LectionSerializer
@list_route(methods=['get'], url_path='get-lections/(?P<pk>[^/]+)')
def get_lection(self, request, pk):
self.pagination_class = OneByOneItems
queryset = self.filter_queryset(self.queryset.filter(course=pk))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
serializers.py
class CourseSerializer(serializers.ModelSerializer):
author = UserCreatorSerializer(many=True)
project = ProjectSerializer(many=True)
class Meta:
model = Course
fields = ('id', 'theme', 'author', 'project')
class LectionSerializer(serializers.HyperlinkedModelSerializer):
choose_course = CourseSerializer(source='course')
class Meta:
model = LectionCourse
fields = ('id', 'title', 'video', 'preview_description', 'number', 'choose_course')
I prefer to use Custom pagination as it will allow you modify your response according to your requirements. This method doesn't require much effort.
Below is my code for this... Hope this will be helpful.
custom_pagination.py
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response
class CustomPagination(LimitOffsetPagination):
def get_paginated_response(self, data):
return Response({
"status": True,
"code": status.HTTP_200_OK,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.count,
'results': data
})
In your view all you need to do is to call two functions, i-e paginate_queryset and the one you created in your pagination class get_paginated_response. "pagination_queryset" takes queryset as parameter and than pass that result to your serializer, finally call "get_paginated_response" which takes serialized data as parameter and in result return response.
page = self.paginate_queryset(query_set)
serializer_class = <Your Serializer>(page, many=True,)
return self.get_paginated_response(serializer_search_user.data)
Finally declare your custom serialization class in "settings.py".
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'<your_app>.<your_peckage>.custom_pagination.CustomPagination',
'PAGE_SIZE': 5
}