Open In App

How to add Pagination in Django Project?

Last Updated : 22 May, 2025
Suggest changes
Share
Like Article
Like
Report

Pagination system is one of the most common features in  blogs, search engine , list of result etc. Seeing the popularity of pagination system django developers have build a Paginator class so that web developers do not have to think of the logic to make paginators. 

What is the Paginator Class?

The Paginator class is located in django/core/paginator.py. It helps divide a list of objects into pages, making it easy to display a subset of objects per page.

Importing Paginator

To use the paginator, import it along with some exceptions from Django:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

Basic Syntax

p = paginator(list_of_objects, no_of_objects_per_page)

  • list_of_objects: This can be a list, tuple, queryset, or any sliceable object with a count() or __len__() method.
  • objects_per_page: Number of objects to display on each page.

Optional Arguments:

  • orphans (int): If the last page has fewer than or equal to this number of objects, they will be added to the previous page. Default is 0.
  • allow_empty_first_page (bool): Whether the first page is allowed to be empty. Default is True..

Steps to Implement Pagination in Django

Prerequisites:

Create or Use a Django Project and App

If you don’t have a Django project or app yet, create them:

django-admin startproject myproject
cd myproject
python manage.py startapp blog

Define Your Model (Post)

In your app’s models.py, define the Post model if not already done:

Python
from django.shortcuts import render from .models import Post from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): posts = Post.objects.all() # fetching all post objects from database p = Paginator(posts, 5) # creating a paginator object # getting the desired page number from url page_number = request.GET.get('page') try: page_obj = p.get_page(page_number) # returns the desired page object except PageNotAnInteger: # if page_number is not an integer then assign the first page page_obj = p.page(1) except EmptyPage: # if page is empty then return last page page_obj = p.page(p.num_pages) context = {'page_obj': page_obj} # sending the page object to index.html return render(request, 'index.html', context) 

Create and Apply Migrations

Run the following commands to create the database table:

python manage.py makemigrations
python manage.py migrate

Add Some Sample Data

You can add posts via the Django admin or shell:

python manage.py shell

Then inside the shell:

from blog.models import Post

Post.objects.create(title="Post 1", author="Author 1", content="Content 1")
Post.objects.create(title="Post 2", author="Author 2", content="Content 2")
# ... create at least 8 posts as in the example

Exit the shell with exit().

Create the View with Pagination

In your app’s views.py, add the pagination code:

Python
from django.shortcuts import render from .models import Post from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): posts = Post.objects.all() paginator = Paginator(posts, 5) # Show 5 posts per page page_number = request.GET.get('page') try: page_obj = paginator.get_page(page_number) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) context = {'page_obj': page_obj} return render(request, 'index.html', context) 

Create a folder named templates inside your app folder (blog/templates/) and inside it create index.html.

Add this template content:

HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Django Paginator example</title> </head> <body> <div class="container"> {% for post in page_obj.object_list %} {# note that the list of posts are in the page_obj.object_list not page_obj #} <h1>{{post.title}}</h1> <small>{{post.author}}</small> <p>{{post.content}}</p> <hr/> {% endfor %} </div> <center> {%if page_obj.has_previous %} {# whether the previous page exists #} <a href="?page={{page_obj.previous_page_number}}"><</a> {# link to the prev page #} {% endif %} <span>{{page_obj.number}}</span> {# the current page number #} {%if page_obj.has_next %} {# whether the next page exists #} <a href="?page={{page_obj.next_page_number}}">></a> {# link to the next page #} {% endif %} </center> </body> </html> 
  • Use page_obj.object_list to iterate through the posts on the current page.
  • Use page_obj.has_previous and page_obj.has_next to conditionally show navigation arrows.
  • Clicking the arrows sends a GET request with the page parameter to navigate pages.

Configure URLs

In your app, create (or edit) urls.py (blog/urls.py):

Python
from django.urls import path from .views import index urlpatterns = [ path('', index, name='index'), ] 

Then include your app’s URLs in the project’s main urls.py (myproject/urls.py):

Python
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('blog.urls')), # Make sure your app is included here ] 

Run the Server

Start the Django development server:

python manage.py runserver

Output:

In the image we have send the value of the page number with a GET request ( denoted with rectangle). You can see the pagination in the bottom of the image ( marked with rectangle ).

Here is another image of the last page:


Similar Reads