In this Django Pagination article i want to show you Pagination Complete Example, so when you are going to develop a blog in Django you will realize to separate the list of posts across several pages. Django has a built in pagination class to allows you to manage paginated data. Under the hood, all methods of pagination use the Paginator
class. It does all the heavy lifting of actually splitting a QuerySet
into Page
objects.
Also you can check my the previous articles in django .
1: How To Build News Application In Django
2: Django Sending Email To Gmail Account
There are two ways that you can do pagination in django, the first way is using function based view and the second way is using class based views.
OK now first of all you need to create a new django project using this command. i have called the project MyProject
1 |
django-admin startproject ProjectName |
First of all you need to change directory to the created project and after that you need to create an App, i have called the app MyApp.
1 |
python manage.py startapp MyApp |
Also you need to add you newly created app in your settings.py(INSTALLED_APPS).
1 2 3 4 5 6 7 8 9 |
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'MyApp' ] |
OK now after this you need to do migrate your django project
1 |
python manage.py migrate |
Also you need to create a templates folder because we need to add some html files to our templates folder, make sure that after creating templates folder you need to open your settings.py and add the templates directory in to DIRS section like this.
1 2 3 4 |
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates'], |
1: Pagination in Function Based View
OK now first of all you need to open your models.py file in your app and create your model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from django.db import models from django.utils import timezone # Create your models here. class Post(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=100) body = models.TextField() publish = models.DateTimeField(default=timezone.now()) def __str__(self): return self.title |
basically we have a model that has four fields with out id.
After that you need to do migrations like this.
1 |
python manage.py makemigrations |
1 |
python manage.py migrate |
First of all you need to open your views.py file and create your view function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from django.shortcuts import render from .models import Post from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # Create your views here. def Index(request): post_list = Post.objects.all() paginator = Paginator(post_list, 2) page = request.GET.get('page') try: posts = paginator.page(page) except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request, 'index.html', {'page':page,'posts':posts}) |
and you can see we have done our pagination in the Index view function
OK now you need to create a new urls.py in your app that you have created. and link your view function
in there like this.
1 2 3 4 5 6 7 8 |
from django.urls import path from .views import Index urlpatterns = [ path('', Index), ] |
And also you need to include your app urls.py in your main project urls.py like this
1 2 3 4 5 6 7 |
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('MyApp.urls')) ] |
OK now in your templates folder you need to create two html files like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> </head> <body> <div class = "jumbotron"> {% for post in posts %} <h1 class="display-4">{{post.title}}</h1> Published {{post.publish}} by {{post.author}} {{post.body|truncatewords:30|linebreaks}} <hr class="my-4"> {% endfor %} </div> {% include "pagination.html" with page=posts %} </body> </html> |
So this is our index html file, also you can see at the top i have added Bootstrap CDN link because iam going to use some bootstrap styles for my pagination. and this code is for including of our pagination file that we have not created yet.
1 |
{% include "pagination.html" with page=posts %} |
Since the Page object we are passing to the template is called posts, we include the pagination template in the post list template, passing the parameters to render it correctly. You can follow this method to reuse your pagination template in paginated views of different models.
Now this is our pagination.html file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<nav aria-label="Page navigation example" > <ul class="pagination"> <li class="page-item"> {% if page.has_previous %} <a class="page-link" href="?page={{page.previous_page_number}}">Previous</a> {% endif %} </li> <li class="page-item"> <a class="page-link">Page {{page.number}} of {{page.paginator.num_pages}}</a> </li> <li class="page-item"> {% if page.has_next %} <a class="page-link" href="?page={{page.next_page_number}}">Next</a> {% endif %} </li> </ul> </nav> |
Now you can run your project and you will see the pagination.
1 |
python manage.py runserver |
And this will be the result for pagination.
2: Class Based View Pagination
So for class based view pagination we need to bring some changes in our views.py file like this. i have commented the first one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from django.shortcuts import render from .models import Post from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.views.generic import ListView # Create your views here. ''' def Index(request): post_list = Post.objects.all() paginator = Paginator(post_list, 2) page = request.GET.get('page') try: posts = paginator.page(page) except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request, 'index.html', {'page':page,'posts':posts}) ''' class PostList(ListView): queryset = Post.objects.all() context_object_name = 'posts' paginate_by = 2 template_name = 'index.html' |
django.views.generic.list.ListView
provides a builtin way to paginate the displayed list. You can do this by adding a paginate_by
attribute to your view class, This limits the number of objects per page and adds a paginator
and page_obj
to the context
. To allow your users to navigate between pages, add links to the next and previous page, in your template.
Now after this you need to open your urls.py and comment the previous view. and add the class based view
1 2 3 4 5 6 7 8 |
from django.urls import path from .views import PostList urlpatterns = [ #path('', Index), path('', PostList.as_view()) ] |
you can see at the top we have imported the PostList, In order to keep pagination working, we have to use the right page. object that is passed to the template. Django’s ListView generic view passes the selected page in a variable called page_obj, so you have to edit your index.html template accordingly to include the paginator using the right variable, as follows
1 |
{% include 'pagination.html' with page=page_obj %} |
So if you run the project the result will be the same.
Also you can watch the complete video for this article.
Subscribe and Get Free Video Courses & Articles in your Email
Thank you very much for the information.I sincerely appreciate your help.
welcome
How to paginate using jquery aja?