Django — Step 11

Pagination

Brian Mayrose
Jul 19, 2019 · 3 min read

We are continuing from step 10:


Let’s add pagination to the display_1 index page. The documentation for pagination can be found here:

The first thing to do is import Paginator, EmptyPage, and PageNotAnInteger from django.core.paginator at the top of display_1/views.py

The second thing we need to do is update the index definition with 3 new variables:

  • paginator
  • page
  • paged_items.

Then we just update the context variables dictionary value to paged_listings:

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import item
def index(request):
dbitems = item.objects.all().order_by('-list_date').filter(is_published=True)
paginator = Paginator(dbitems, 2)
page = request.GET.get('page')
paged_items = paginator.get_page(page)
context = {'dbitems': paged_items }
return render(request, 'display_1/index.html', context)

The paginator variable is set to Paginator which takes 2 arguments, dbitems and the number of items you want displayed per page. It is set to 2 so we can test it out with the 6 items we have.

The page variable is set to request.Get.get(‘page’) and paged_listings is set to paginator.get_page(page)

save the views.py file and open the templates/display_1/index.html file.

Now we need to add a new if/else Jinja tags calling the pagination just below the ‘section’ HTML tag in the index.html template:

</section>
<div class="container ">
<div class="col-md-5 ">
</div>
{% if dbitems.has_other_pages %}
<ul class="pagination">
{% if dbitems.has_previous %}
<li class="page-item">
<a href="?page={{listings.previous_page_number}}"
class="page-link">
&laquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">
&laquo;
</a>
</li>
{% endif %}
{% for i in dbitems.paginator.page_range %}
{% if dbitems.number == i %}
<li class="page-item active">
<a class="page-link">{{i}}</a>
</li>
{% else %}
<li class="page-item">
<a href="?page={{i}}" class="page-link">{{i}}</a>
</li>
{% endif %}
{% endfor %}
{% if dbitems.has_next %}
<li class="page-item">
<a href="?page={{dbitems.next_page_number}}"
class="page-link">
&raquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">
&raquo;
</a>
</li>
{% endif %}
</ul>
{% endif %}
</div>
</body>
{% endblock %}

Jinja can use the filter, has_other_pages to check if more items are available for more pages.

{% if dbitems.has_other_pages %}

We are calling 2 if statements and one for loop.

The first if statement uses the has_previous pagination method. This will display a link to any listings that come before the current page of listings. The anchor tag takes advantage of pagination’s previous_page_number method.

we follow this with an else statement and a list item with the class disabled that hides the link if no previous items are found:

{% if dbitems.has_previous %}
<li class="page-item">
<a href="?page={{listings.previous_page_number}}"
class="page-link">
&laquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">
&laquo;
</a>
</li>
{% endif %}

Next is a Jinja for loop that iterates over the items in the database.

Dependent on the number of items found and the number of items to set to be displayed in the view definition, the if/else statements determine if the current page should be given the class active and also adds the links to more pages of items:

{% for i in dbitems.paginator.page_range %}
{% if dbitems.number == i %}
<li class="page-item active">
<a class="page-link">{{i}}</a>
</li>
{% else %}
<li class="page-item">
<a href="?page={{i}}" class="page-link">{{i}}</a>
</li>
{% endif %}
{% endfor %}

Then just like we did for the previous arrows, we need to make the next arrows.

This will be an if statement just like the has_previous method, but using the has_next method instead and replacing the left arrows with right arrows:

{% if dbitems.has_next %}
<li class="page-item">
<a href="?page={{dbitems.next_page_number}}"
class="page-link">
&raquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">
&raquo;
</a>
</li>
{% endif %}
</ul>
{% endif %}

Save the template files and restart the server and you will see the pagination links at the bottom of the display_1 page:


In the next step, we will set up the display_1_item view definition so that we can click on an item and be taken to a page with the details of that item.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade