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
- 1. Introduction
- 2. Installation and setup
- 3. How things work
- 4. The first Django app
- 5. Your first view
- 6. Your first template
- 7. Testing our site
- 8. Extending templates
- 9. Your first model
- 10. The admin interface
- 11. Showing contents from the model
- 12. Another app (category)
- 13. Connecting two models
- 14. Show list of categories
- 15. Category detail page
- 16. Separate url files and why
- 17. Adding tasks in the front end
- 18. Editing tasks
- 19. Completing and deleting tasks
- 21. Prettying up the design a little bit
- 22. Make it possible to sign up
- 23. Logging in
- 24. Logging out
- 25. Show only your data
- 26. Creating a model function
- 27. Template filters
- 28. Pagination