Pagination - 30 days of Django

Pagination - 30 days of Django

/ #Django


Learn how to add pagination so you can split your items into multiple pages.

Django has built in support and functionality for paginating data. So this will be utilized in this Django project.

Let's open up the task/views.py file, and begin there with these changes:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger # New, 1
...

@login_required
def frontpage(request):
    if request.method == 'POST':
        form = TaskForm(request.POST)

        if form.is_valid():
            form.save()
    else:
        form = TaskForm()

    title = 'This is a variable'
    tasks = Task.objects.filter(user=request.user)
    categories = Category.objects.all()

    page = request.GET.get('page', 1)
    paginator = Paginator(tasks, 10)
    try:
        tasks = paginator.page(page)
    except PageNotAnInteger:
        tasks = paginator.page(1)
    except EmptyPage:
        tasks = paginator.page(tasks.num_pages)

    return render(request, 'task/frontpage.html', {'title': title, 'tasks': tasks, 'categories': categories, 'form': form})

As you can see here, there are a few new lines. First, we import three methods from the paginator class.

Then, we just get all of the tasks like we've done earlier.
Next step is to get the page number from the URL, if it's not there, we default it to 1.

Next, we set up a Paginator, pass in the tasks and the limit per page (10). Then we check if there is an actual page, if the page is empty and simlar.

So when that's done, we can go to the template and implement it there. Open up frontpage.html:

{% extends 'task/base.html' %}

{% block content %}
    <div class="frontpage">
        <h1>{{ title }}</h1>

        <div class="columns">
            <div class="column is-8">
                <h2>Tasks</h2>

                ..

                {% for task in tasks %}
                    <div>
                        <p>{{ task.title }} - {{ task.created_at }}</p>
                    </div>
                {% endfor %}

                {% if tasks.has_other_pages %}
                    <nav class="pagination" role="navigation" aria-label="pagination">
                        {% if posts.has_previous %}
                            <a class="pagination-previous" href="?page={{ tasks.previous_page_number }}">Previous</a>
                        {% endif %}

                        {% if tasks.has_next %}
                            <a class="pagination-next" href="?page={{ tasks.next_page_number }}">Next</a>
                        {% endif %}

                        <ul class="pagination-list">
                            {% for i in tasks.paginator.page_range %}
                                {% if tasks.number == i %}
                                    <li>
                                        <a class="pagination-link is-current">{{ i }}</a>
                                    </li>
                                {% else %}
                                    <li>
                                        <a class="pagination-link" href="?page={{ i }}">{{ i }}</a>
                                    </li>
                                {% endif %}
                            {% endfor %}
                        </ul>
                    </nav>
                {% endif %}
            </div>

            ...
        </div>
    </div>
{% endblock %}

The code for this is more or less self explanatory. We use the tasks object to check if there are pages, if there are any previous pages and similar.

Table of contents

Comments

No comments yet...

Add comment

Newsletter

Subscribe to my weekly newsletter. One time per week I will send you a short summary of the tutorials I have posted in the past week.