Paginate records in django rest framework (DRF)

Few days ago, I was working on an API which responds to a React based Application. Initially there were lesser records and we didn’t need to apply pagination. Suddenly we feel that the number of records to show on application are increasing drastically and we should paginate records in all the APIs. We follow django official doc and are able to apply the pagination. But, there was duplicate code at every where we paginate the queryset. So I write a helper to remove duplicate code. Also, whenever I want to apply pagination in a new project, I can simply place this helper in a new project and can use it. You can use this helper in your project as well.

Create pagination_helper.py file as below:

from django.core.paginator import Paginator

def paginateRecords(queryset, **kwargs):
   currentPage = int(kwargs.get('currentPage', 1))
   recordPerPage = int(kwargs.get('recordPerPage', 10))
   p = Paginator(queryset, recordPerPage)
   currentPageRecords = p.page(currentPage)

   # get counters
   total_records = p.count
   total_pages = p.num_pages
   has_next = currentPageRecords.has_next()
   has_previous = currentPageRecords.has_previous()
   paginationData = {
                       "total_records": total_records,
                       "total_pages": total_pages,
                       "current_page_no": int(currentPage),
                       "has_next": has_next,
                       "has_previous": has_previous,
                       "record_per_page": recordPerPage,
                   }

   return {
           "queryset": currentPageRecords.object_list,
           "paginationData": paginationData
       }

Integration: Import your helper where you want to use it. Here under, “core” is the django project name in core.pagination_helper. Don’t be confused by the keyword “core”. It can be according to your file structure. What we want is to just import the pagination helper.

Views.py

from core.pagination_helper import paginateRecords

queryset = queryset.all().order_by('-id')
currentPage = int(request.GET.get('page', 1))
currentPage = 1 if currentPage < 1 else currentPage

recordPerPage = request.GET.get('page_size', 20)

paginatedResultset = paginateRecords(queryset, currentPage=currentPage, recordPerPage=recordPerPage)
# print(paginatedResultset['paginationData'])
# print(type(paginatedResultset['queryset']))

resultSet = YourSerializer(paginatedResultset['queryset'],
                                               context={"request": request},
                                               many=True)

return JsonResponse({"data":resultSet.data, "paginationData": paginatedResultset['paginationData'], "status": 200})

Here is the sample response:

{
    "data": [
        {
            "customer": {
                "id": 2440,
                "name": "Abhishek"
            },
            "schedule_date": "Feb. 01, 2020",
            "start_time": "04:00 PM",
            "end_time": "05:00 PM",
            "title": "Visualisation",
            "is_new": false
        }
    ],
    "paginationData": {
        "total_records": 3121,
        "total_pages": 3121,
        "current_page_no": 1041,
        "has_next": true,
        "has_previous": true,
        "record_per_page": 1
    },
    "status": 200
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top
Shares