Pagination is the most basic and important of any website. Pagination greatly improves the user experience. With pagination, user can escape from scrolling the long list of contents. In this tutorial, we’ll learn how to add pagination to our Django website. And doing this in Django is very easy (I promise!). Ready to start?
Project setup
Let’s setup our django project and a django app:
django-admin startproject django_pagination cd django_pagination django-admin startapp app
Change the django_pagination/urls.py file as below:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('app.urls')) ]
Add our app to the list of INSTALLED_APPS in your django_pagination/settings.py:
.... INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app' ] ....
We’re done with basic project setup.
Making our app
Make a file called urls.py in your app/ folder and add the lines below to it:
from django.urls import path from . import views urlpatterns = [ path('', views.pagination, name="pagination") ]
Now, let’s make a model to store our data that should get paginated. Make a simple model as below in your app/models.py file:
from django.db import models class Post(models.Model): title = models.CharField(max_length=200) description = models.TextField() def __str__(self): return self.title
And now we’ll write our one and only function in our app/views.py. Add the lines below to your app/views.py:
from django.shortcuts import render from .models import Post from django.core.paginator import Paginator def pagination(request): post_models = Post.objects.all() paginator = Paginator(post_models, 2) page_number = request.GET.get('page') page_object = paginator.get_page(page_number) return render(request, 'index.html', {'page_objects': page_object})
We’re importing a class called Paginator
from django.core.paginator. This enables us to use pagination in Django. We’re initializing a paginator object from this Paginator
class. And we’re initializing this with the list (Query set to be precise) of objects of our Post model and a number denoting the maximum number of objects to be displayed per page. In our case, we passed a number 2, so a maximum of 2 post objects will get displayed in our page.
Next, we gathered the current page number by request.GET.get('page')
. This is inbuilt template variable that is controlled by Pagination
class and what it does is that it grabs the current page number. And this page number is used to get the objects corresponding to that page by paginator.get_page(page_number)
. Finally, page_object
contains all the objects that corresponds to that particular page number.
This is a broad overview of what is happening but feel free to explore the Django docs for pagination.
Adding our templates
Finally, we need to setup our templates. Create a folder called templates in your app/ directory. And make a file with name index.html in that folder you created. Add the followind content to it:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta name="Description" content="Enter your description here" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"> <title>Pagination</title> </head> <body> <div class="container mt-5"> {% for page in page_objects %} <div style="border: 1px solid black"> {{page.title}} <br> {{page.description}} </div> {% endfor %} </div> <div class="text-center container mt-5"> {% if page_objects.has_previous %} <a class="poppins-font p-2" href="?page={{page_objects.previous_page_number}}"> Previous </a> {% endif %} <a href="" class="poppins-font p-2 active-btn text-dark" style="background-color: #00e1ff;"> {{page_objects.number}} </a> {% if page_objects.has_next %} <a class="poppins-font p-2" href="?page={{page_objects.next_page_number}}"> Next </a> {% endif %} </div> </body> </html>
I’m using bootstrap for my styling. What we’re basically doing is, firstly we’re displaying the list of page_objects. Secondly, we’re making a couple of conditional statements. To put these simply, we’ll display previous link only when our page_objects has some objects before them (Previous pages). We’ll display the current page number. Finally, we’ll display next only when our page_objects has some more objects to accomodate in the next page(s). That’s it! Please take a look at href of each anchor tag for better understanding.
Running our project
Now, before running our project, we need to execute the following statement:
python manage.py makemigrations python manage.py migrate
Then we need to add some data to our Page model. We’ll do this in our admin panel by creating a superuser with the following command:
python manage.py createsuperuser
Now, for our Page model to get displayed in our admin panel we need to register our model, to do this add the following lines to your app/admin.py:
from django.contrib import admin from .models import Post admin.site.register(Post)
Run the server with the following command:
python manage.py runserver
Open the admin panel by visiting 127.0.0.1:8000/admin in your favourite browser and login to the admin panel with the credentials you’ve used to create the superuser. There open Posts table and add a few dummy models with title and description.
After adding dummy models, Visit 127.0.0.1:8000. Then you’ll see our output with pagintion.
Get the code a my Github repo: https://github.com/Chandu-4444/django_pagination