Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Django 3 By Example

You're reading from   Django 3 By Example Build powerful and reliable Python web applications from scratch

Arrow left icon
Product type Paperback
Published in Mar 2020
Publisher Packt
ISBN-13 9781838981952
Length 568 pages
Edition 3rd Edition
Languages
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Antonio Melé Antonio Melé
Author Profile Icon Antonio Melé
Antonio Melé
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface 1. Building a Blog Application 2. Enhancing Your Blog with Advanced Features FREE CHAPTER 3. Extending Your Blog Application 4. Building a Social Website 5. Sharing Content on Your Website 6. Tracking User Actions 7. Building an Online Shop 8. Managing Payments and Orders 9. Extending Your Shop 10. Building an E-Learning Platform 11. Rendering and Caching Content 12. Building an API 13. Building a Chat Server 14. Going Live 15. Other Books You May Enjoy
16. Index

Adding pagination

When you start adding content to your blog, you might easily reach the point where tens or hundreds of posts are stored in your database. Instead of displaying all the posts on a single page, you may want to split the list of posts across several pages. This can be achieved through pagination. You can define the number of posts you want to be displayed per page and retrieve the posts that correspond to the page requested by the user. Django has a built-in pagination class that allows you to manage paginated data easily.

Edit the views.py file of the blog application to import the Django paginator classes and modify the post_list view, as follows:

from django.core.paginator import Paginator, EmptyPage,\
                                  PageNotAnInteger
def post_list(request):
    object_list = Post.published.all()
    paginator = Paginator(object_list, 3) # 3 posts in each page
    page = request.GET.get('page')
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        posts = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        posts = paginator.page(paginator.num_pages)
    return render(request,
                  'blog/post/list.html',
                   {'page': page,
                    'posts': posts})

This is how pagination works:

  1. You instantiate the Paginator class with the number of objects that you want to display on each page.
  2. You get the page GET parameter, which indicates the current page number.
  3. You obtain the objects for the desired page by calling the page() method of Paginator.
  4. If the page parameter is not an integer, you retrieve the first page of results. If this parameter is a number higher than the last page of results, you retrieve the last page.
  5. You pass the page number and retrieved objects to the template.

Now you have to create a template to display the paginator so that it can be included in any template that uses pagination. In the templates/ folder of the blog application, create a new file and name it pagination.html. Add the following HTML code to the file:

<div class="pagination">
  <span class="step-links">
    {% if page.has_previous %}
      <a href="?page={{ page.previous_page_number }}">Previous</a>
    {% endif %}
    <span class="current">
      Page {{ page.number }} of {{ page.paginator.num_pages }}.
    </span>
    {% if page.has_next %}
      <a href="?page={{ page.next_page_number }}">Next</a>
    {% endif %}
  </span>
</div>

The pagination template expects a Page object in order to render the previous and next links, and to display the current page and total pages of results. Let's return to the blog/post/list.html template and include the pagination.html template at the bottom of the {% content %} block, as follows:

{% block content %}
  ...
  {% include "pagination.html" with page=posts %}
{% endblock %}

Since the Page object you are passing to the template is called posts, you 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 the paginated views of different models.

Now open http://127.0.0.1:8000/blog/ in your browser. You should see the pagination at the bottom of the post list and should be able to navigate through pages:

Figure 1.12: The post list page including pagination

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime