WDTUTORIALS

Django - Pagination Examples

Tutorial on how to create and style a pager.

View

from django.shortcuts import render
from blog.models import Post
from django.core.paginator import Paginator # < Import the Paginator class

def home(request):

    posts = Post.objects.all()
    paginator = Paginator(posts, 3) # < 3 is the number of items on each page
    page = request.GET.get('page') # < Get the page number

    posts = paginator.get_page(page) # < New in 2.0!

    return render(request, 'base/home.html', {'posts': posts})

Markup Example 1

<div class="pagination">

  {% if posts.has_previous %}
  <a href="?page=1">First</a>
  <a href="?page={{ posts.previous_page_number }}">Previous</a>
  {% endif %}

  <span>{{ posts.number }}</span>
  <span">of</span>
  <span>{{ posts.paginator.num_pages }}</span>

  {% if posts.has_next %}
  <a href="?page={{ posts.next_page_number }}">Next</a>
  <a href="?page={{ posts.paginator.num_pages }}">Last</a>
  {% endif %}

</div>

Markup Example 2

<div class="pagination">

  {% if posts.has_previous %}
  <a href="?page=1">First</a>
  <a href="?page={{ posts.previous_page_number }}">Previous</a>
  {% endif %}

  {% for num in posts.paginator.page_range %}

    {% if posts.number == num %}
    <span>{{ num }}</span>
    {% elif num > posts.number|add:'-3' and num < posts.number|add:'3' %}
    <a href="?page={{ num }}">{{ num }}</a>
    {% endif %}

  {% endfor %}

  {% if posts.has_next %}
  <a href="?page={{ posts.next_page_number }}">Next</a>
  <a href="?page={{ posts.paginator.num_pages }}">Last</a>
  {% endif %}

</div>

Source for the page range limit: https://stackoverflow.com/a/45717542

More details on how to build the paginated posts object:

View

Import the Paginator class:

from django.core.paginator import Paginator

Call the Paginator class object and give it at least two arguments: the items you want to paginate and the number of items you want to see on each page:

paginator = Paginator(posts, 3)

This will instantiate the paginator object that we can use to access the page items.

Get the pagination page number from the request object:

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

When you request a page, an HttpRequest object is passed to the view. This contains data about the request like the HTTP GET parameters.

In this case we will be sending the page number in the url like this mysite.com/?page=2.

Use the get_page method with the page number to fetch Page object that we will use to access items in any given page:

posts = paginator.get_page(page)

Same as the 2.0 version but we handle invalid and out of range page numbers manually:

View

from django.shortcuts import render
from blog.models import Post
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # < Import these

def home(request):

    posts = Post.objects.all()
    paginator = Paginator(posts, 3)
    page = request.GET.get('page')

    # Handle out of range and invalid page numbers:
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)

    return render(request, 'base/home.html', {'posts': posts})

Blue theme that shows couple of wing pages in addition to the current page. Use the view from the 2.0 Quickstart tab to build the Posts object.

Result

Template

<div class="pagination">

  {% if posts.has_previous %}
    <a class="pagination-action" href="?page=1">
     <i class="fa fa-angle-double-left" aria-hidden="true"></i>
    </a>
    <a class="pagination-action" href="?page={{ posts.previous_page_number }}">
      <i class="fa fa-angle-left" aria-hidden="true"></i>
    </a>
  {% endif %}

  {% for num in posts.paginator.page_range %}

    {% if posts.number == num %}
    <span class="pagination-number pagination-current">{{ num }}</span>
    {% elif num > posts.number|add:'-3' and num < posts.number|add:'3' %}
    <a class="pagination-number" href="?page={{ num }}">{{ num }}</a>
    {% endif %}

  {% endfor %}

  {% if posts.has_next %}
    <a class="pagination-action" href="?page={{ posts.next_page_number }}">
      <i class="fa fa-angle-right" aria-hidden="true"></i>
    </a>
    <a class="pagination-action" href="?page={{ posts.paginator.num_pages }}">
      <i class="fa fa-angle-double-right" aria-hidden="true"></i>
    </a>
  {% endif %}

</div>

Fontawesome

Load fontawesome in the head section:

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

CSS

.pagination {
    text-align: center;
    margin-top: 1em;
}

.pagination-number {
    padding: 0.5em 0.8em;
    border-radius: 2px;
    color: #fff;
    background-color: #6D85C7;
}

.pagination-number:hover, .pagination-current {
    background-color: #3354AA;      
}

.pagination-action {
    margin: 0 0.1em;
    display: inline-block;
    padding: 0.5em 0.5em;
    color: #B9B9B9;
    font-size: 1.3em;
}

.pagination-action:hover, .pagination-previous, .pagination-next {
    color: #3354AA;  
}

Green theme that shows current page and total number of pages. Use the view from the 2.0 Quickstart tab to build the Posts object.

Result

Template

<div class="pagination">

  {% if posts.has_previous %}
    <a class="pagination-action" href="?page=1">
     <i class="fa fa-angle-double-left" aria-hidden="true"></i>
    </a>
    <a class="pagination-action" href="?page={{ posts.previous_page_number }}">
      <i class="fa fa-angle-left" aria-hidden="true"></i>
    </a>
  {% endif %}

  <span class="pagination-current">{{ posts.number }}</span>
  <span class="pagination-of">of</span>
  <span class="pagination-total">{{ posts.paginator.num_pages }}</span>

  {% if posts.has_next %}
    <a class="pagination-action" href="?page={{ posts.next_page_number }}">
      <i class="fa fa-angle-right" aria-hidden="true"></i>
    </a>
    <a class="pagination-action" href="?page={{ posts.paginator.num_pages }}">
      <i class="fa fa-angle-double-right" aria-hidden="true"></i>
    </a>
  {% endif %}

</div>

Fontawesome

Load fontawesome in the head section:

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

CSS

.pagination {
    text-align: center;
    margin-top: 1em;
}

.pagination-current, .pagination-total {
    padding: 0.5em 0.8em;
    border-radius: 2px;
    color: #fff;
    background-color: #30BF61;  
}

.pagination-total {
    background-color: #B9B9B9;
}

.pagination-action {
    margin: 0 0.1em;
    display: inline-block;
    padding: 0.5em 0.5em;
    color: #B9B9B9;
    font-size: 1.3em;
}

.pagination-of {
    color: #B9B9B9;
    padding: 0 1em;
}


.pagination-action:hover {
    color: #3354AA;  
}

Samuli Natri built his first website in the late 90’s. He is very passionate about web technologies. He attended Helsinki University Of Technology (Computer Science) and Helsinki University (Social Sciences). He is the founder of WDTutorials.com.

Latest Tutorial Pagination Examples

Copyright @ 2018 WDTutorials.com. All rights reserved. Privacy policy.Terms Of Service.