To add pagination to the list view of the movies, follow these steps:
- Import the necessary pagination classes from Django into the views.py file. We will add pagination management to the movie_list view just after filtering. Also, we will slightly modify the context dictionary by assigning page to the object_list key:
# movies/views.py
from django.conf import settings
from django.core.paginator import (EmptyPage, PageNotAnInteger,
Paginator)
from django.shortcuts import render
from .models import Genre, Director, Actor, Movie, RATING_CHOICES
from .forms import MovieFilterForm
PAGE_SIZE = getattr(settings, "PAGE_SIZE", 15)
def movie_list(request):
qs = Movie.objects.order_by("title")
form = MovieFilterForm(data=request.GET)
# ... filtering goes here...
paginator = Paginator(qs, PAGE_SIZE)
page_number = request.GET.get("page")
try:
page = paginator.page(page_number)
except PageNotAnInteger:
# If page is not an integer, show first page.
page = paginator.page(1)
except EmptyPage:
# If page is out of range, show last existing page.
page = paginator.page(paginator.num_pages)
context = {
"form": form,
"facets": facets,
"object_list": page,
}
return render(request, "movies/movie_list.html", context)
- In the template, we will add pagination controls after the list of movies, as follows:
{# templates/movies/movie_list.html #}
{# ... #}
{% block content %}
{# ... #}
{% if object_list.has_other_pages %}
<nav aria-label="Movie list pagination">
<ul class="pagination">
{% if object_list.has_previous %}
<li class="page-item">
<a class="page-link"
href="{% modify_query
page=object_list.previous_page_number %}">
«</a></li>
{% else %}
<li class="page-item disabled">
<span class="page-link">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span></span></li>
{% endif %}
{% for page_number in object_list.paginator.page_range %}
{% if page_number == object_list.number %}
<li class="page-item active">
<span class="page-link">{{ page_number }}
<span class="sr-only">(current)</span></span>
</li>
{% else %}
<li class="page-item">
<a class="page-link"
href="{% modify_query page=page_number %}">
{{ page_number }}</a>
</li>
{% endif %}
{% endfor %}
{% if object_list.has_next %}
<li class="page-item">
<a class="page-link"
href="{% modify_query
page=object_list.next_page_number %}">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span></a></li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock %}
NOTE: Template tags in the previous snippet have been split across lines for legibility but, in practice, template tags must be on a single line, and so cannot be split in this manner.