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:
- We create an instance of the
Paginator
class with the number of objects we want to display on one page. - We get the
page GET
parameter, which points to the current page. - We retrieve objects for the desired page by calling the page() method of the
Paginator
method. - 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. - 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.