Django Blog #17: Adding Pagination

by Alex
Django Blog #17: Adding Pagination
When adding content to a blog, you will quickly come to the conclusion that it is better to divide the list of posts into several pages. Django has a built-in pagination class that allows you to do this very quickly. Edit the views.py file of the blog application to import the Paginator class and change 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 per page  
    page = request.GET.get('page') 
    try 
        posts = paginator.page(page) 
   except PageNotAnInteger  
       # If the page is not an integer, put the first page  
        posts = paginator.page(1) 
   except EmptyPage  
       # If the page is bigger than the maximum, deliver the last page of the results  
        posts = paginator.page(paginator.num_pages) 
   return return(request,  
	         'blog/post/list.html',  
		 {'page': page,  
		   { 'posts': posts})

Here’s how this class works:

  1. We create an instance of the Paginator class with the number of objects we want to display on one page.
  2. We get the page GET parameter, which points to the current page.
  3. We retrieve objects for the desired page by calling the page() method of the Paginator method.
  4. If the page parameter is not an integer, we return the first result page. If it is larger than the last results page, we return the last page.
  5. We pass the page number and the resulting objects to the template.

Now you need to create a template to display the paginator so that it can be used in any template with pagination. In the templates/applications blog folder, create a new file and name it pagination.html. Add the following code there:

<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 to get a Page object to render the “Previous” and “Next” links, as well as to display the current page and the total number of result pages. Let’s go back to the blog/post/list.html template and add the pagination.html template at the bottom of the {% content %} block:

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

Because the Page object that is passed to the template is called posts, let’s pass the pagination template to the post list template along with parameters for correct rendering. This method can be used to use the pagination template in page views of different models. Now open https://127.0.0.1:8000/blog/ in your browser. You will see the page navigation elements at the bottom and be able to navigate through them.

Related Posts

LEAVE A COMMENT