16- Django Pagination

Django provides high-level and low-level ways to help you manage paginated data – that is, data that’s split across several pages, with “Previous/Next” links.

In this post, I will add pagination for moviesapp. Currently the moviesapp view is like below.

def moviesapp(request):
    movies = Movie.objects.all()
    return render(request, 'moviesapp.html', {'movies': movies})

 

Import Paginator class to your views.py

 

from django.core.paginator import Paginator


def moviesapp(request):
    movies = Movie.objects.all()
#give paginator a list of objects and number of items you want to display on each page
    paginator_obj = Paginator(movies, 12)
    page_number = request.GET.get('pg')
    movies = paginator_obj.get_page(page_number)
    return render(request, 'moviesapp.html', {'movies': movies})

 

From Bootstrap.com, copy a pagination and paste it to your template. Change the labels like below (First, Last, the value of current, previous and next page numbers)

moviesapp.html

<!--pagination -->
<nav aria-label="Page navigation example">
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="#">First</a></li>
    <li class="page-item"><a class="page-link" href="#">{{movies.previous_page_number}}</a></li>
    <li class="page-item"><a class="page-link" href="#">{{movies.number}}</a></li>
    <li class="page-item"><a class="page-link" href="#">{{movies.next_page_number}}</a></li>
    <li class="page-item"><a class="page-link" href="#">Last</a></li>
  </ul>
</nav>
<!--pagination ends-->

{% endblock content %}

 

Now lets define the links. (obj.paginator.num_pages simply means last page)

<!--pagination -->
<nav aria-label="Page navigation example">
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="/?pg=1">First</a></li>
    <li class="page-item"><a class="page-link" href="/?pg={{movies.previous_page_number}}">{{movies.previous_page_number}}</a></li>
    <li class="page-item"><a class="page-link" href="/?pg={{movies.number}}">{{movies.number}}</a></li>
    <li class="page-item"><a class="page-link" href="/?pg={{movies.next_page_number}}">{{movies.next_page_number}}</a></li>
    <li class="page-item"><a class="page-link" href="/?pg={{movies.paginator.num_pages}}">Last</a></li>
  </ul>
</nav>
<!--pagination ends-->

{% endblock content %}

 

We are using  First and Last buttons, what if there is no previous or next? Therefore I need to add if-else statement in my pagination.

<!--pagination -->
<nav aria-label="Page navigation example">
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="/?pg=1">First</a></li>
    {% if movies.has_previous %}
    <li class="page-item"><a class="page-link" href="/?pg={{movies.previous_page_number}}">{{movies.previous_page_number}}</a></li>
    {% endif %}
    <li class="page-item"><a class="page-link" href="/?pg={{movies.number}}">{{movies.number}}</a></li>
    {% if movies.has_next %}
    <li class="page-item"><a class="page-link" href="/?pg={{movies.next_page_number}}">{{movies.next_page_number}}</a></li>
    {% endif %}
    <li class="page-item"><a class="page-link" href="/?pg={{movies.paginator.num_pages}}">Last</a></li>
  </ul>
</nav>
<!--pagination ends-->

{% endblock content %}