Pagination in Django: A Complete Guide to Paginator, Page Objects, ListView Pagination, and Function-Based Views

This article explains how pagination works in Django. It covers the Paginator class, Page object methods, how to paginate data in ListView, and how to use Paginator in function-based views. Practical examples and template snippets are included.

Django pagination, Paginator, Page objectListView pagination, get_pagepaginate_by, Django views

~3 min read • Updated Mar 15, 2026

Introduction

Pagination is essential when displaying large datasets in a user-friendly way. Django provides both high-level and low-level tools to split data across multiple pages with “Previous/Next” navigation. At the core of this system is the Paginator class.


The Paginator Class

The Paginator class handles splitting data into pages. It accepts:

  • a list or tuple
  • a Django QuerySet
  • any object with count() or __len__()

Basic Example


from django.core.paginator import Paginator

objects = ["john", "paul", "george", "ringo"]
p = Paginator(objects, 2)

Key attributes:

  • p.count → total number of items
  • p.num_pages → total number of pages
  • p.page_range → range of page numbers

Accessing a Page


page1 = p.page(1)
page1.object_list  # ['john', 'paul']

Useful Page Object Methods

  • has_next()
  • has_previous()
  • has_other_pages()
  • next_page_number()
  • previous_page_number()
  • start_index()
  • end_index()

Invalid page numbers raise EmptyPage.


Paginating a ListView

Django’s ListView includes built‑in pagination support. To enable it, simply set paginate_by.


from django.views.generic import ListView
from myapp.models import Contact

class ContactListView(ListView):
    paginate_by = 2
    model = Contact

This automatically adds two context variables:

  • paginator
  • page_obj

Template Example


{% for contact in page_obj %}
    {{ contact.full_name|upper }}
{% endfor %}

Using Paginator in a Function-Based View

You can also use Paginator directly inside a function-based view.


from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import Contact

def listing(request):
    contact_list = Contact.objects.all()
    paginator = Paginator(contact_list, 25)

    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    return render(request, "list.html", {"page_obj": page_obj})

The template can use the same pagination controls shown in the ListView example.


Conclusion

Django’s pagination system is simple yet powerful. With Paginator, ListView, and get_page(), you can efficiently display large datasets across multiple pages and provide smooth navigation for your users.

Written & researched by Dr. Shahin Siami