Simple Pagination in Django

Oct. 22, 2020, 8:20 a.m.

Pagination refers to organizing returned data in multiple pages, rather than displaying everything on one page. Therefore we need a way of moving from page one, to two, to three e.t.c. This article focuses on how to achieve that using Django.

I will be using this example app on github to explain how the whole process works.

Here is our views.py file


from django.core.paginator import Paginator
from django.shortcuts import render

from uploads.models import Document

def home(request):

    documents = Document.objects.all()

    paginator = Paginator(documents, 2) # Show 2 documents per page.

    page_number = request.GET.get('page')

    page_obj = paginator.get_page(page_number) 

    return render(request, 'uploads/home.html', { 'page_obj' : page_obj })

Explanation

The first line is : documents = Document.objects.all() and it simply gets all documents in the database and the result of this operation is assigned to the documents variable.

The socond line is : paginator = Paginator(documents, 2) . Here we are using the Paginator class to help us split the results of Documents into pages and each page has only two items.

In the third line we have page_number = request.GET.get('page') .

  • I will start with request.GET , this contain GET variables and they usuually appear in the address bar , e.g http://127.0.0.1:8000/?page=2 .
  • The .get() is a python method that is normally used to return the value of items with a specific key from a dictionary. If nothing is found None is returned.

so this line page_number = request.GET.get('page') simply means we are getting the value of a GET variable that has a name of 'page' and then we assign that to page_number variable.

In the fourth line we have : page_obj = paginator.get_page(page_number) . This line returns a Page object and If the page isn’t a number, it returns the first page.

Now that we are done with views.py file , here is how our template looks like


<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>

Lets divide the above code into three parts, the first part is


{% if page_obj.has_previous %}
   <a href="?page=1">&laquo; first</a>
   <a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}

Here we are checking if the page object has previous page, if so then add links to the first page and previous page.

This line ?page=1 means we are passing data to the server using the GET method, we are passing the value of 1 to the page parameter.

The next part is

<span class="current">
  Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>

The above line shows the current page number against total number of pages.

The last part is

{% if page_obj.has_next %}
  <a href="?page={{ page_obj.next_page_number }}">next</a>
  <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}

This line checks if the page object has next page, if so show links for the next page and the last page, And thats all.

A sample image of how pagination looks like, take a look at the bottom part, we have page 1 of 2 next and last.

sample pagination image


Resources

Keep Learning