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.
To create a custom pagination class, first create a paginations.py file in your app folder and create a class that inherits from an existing DRF paginator. The parameters given in this custom paginator class will enable you to provide a page_size query parameter to determine the size of each page.
Django provides a few classes that help you manage paginated data – that is, data that's split across several pages, with “Previous/Next” links. REST framework includes support for customizable pagination styles. This allows you to modify how large result sets are split into individual pages of data.
For pagination in Django models, you need to use limit offset. Suppose you have 20 rows in a queryset and you want to access the data in batches of 5. The syntax is [OFFSET:OFFSET+LIMIT] where offset would be the no. of rows which we want to skip and the limit is the total no.
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')
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
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
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With