Summary: in this tutorial, you’ll learn how to use the Django ListView
to display a list of tasks for the Todo list application.
This tutorial begins where the Django Todo App tutorial left off.
Introduction to the class-based views #
In the previous tutorials, you have learned how to build a blog application using function-based views.
The function-based views are simple but flexible. In the earlier versions, Django only supported function-based views. Later, Django added support for class-based views that allow you to define views using classes.
Class-based views are an alternative way to implement views. They do not replace the function-based views. However, they have some advantages in comparison with the function-based views:
- Organize code related to HTTP methods like
GET
andPOST
using separate methods, instead of conditional branching in the same function. - Leverage multiple inheritances to create reusable view classes.
We’ll use the class-based views to build the Todo application.
You can download the final code for this Django ListView tutorial here.
Defining a class-based view #
To display a list of objects, you define a class that inherits from the ListView
class. For example, the following defines the TaskList
class in the views.py
of the todo
application:
from django.shortcuts import render from django.views.generic.list import ListView from .models import Task class TaskList(ListView): model = Task context_object_name = 'tasks' # ...
Code language: Python (python)
The TaskList
is a class based-view that inherits from the ListView
class. In the TaskList
class, we define the following attributes:
model
specifies the objects from which model you want to display. In this example, we use theTask
model. Internally, Django will query all objects from theTask
model (Task.objects.all()
) and pass it to a template.context_object_name
specifies the variable name of the model list in the template. By default, Django usesobject_list
. However, the nameobject_list
is quite generic. Therefore, we override thecontext_object_name
by setting its value totasks
.
By convention, the TaskList
class will load the todo/task_list.html
template. The template name follows this convention:
app/model_list.html
Code language: Python (python)
If you want to set a different name, you can use the template_name
attribute. In this tutorial, we’ll use the default template name, which is task_list.html
.
Define a route #
Change the urls.py
of the todo
application to the following:
from django.urls import path from .views import home, TaskList urlpatterns = [ path('', home, name='home'), path('tasks/', TaskList.as_view(),name='tasks'), ]
Code language: Python (python)
How it works.
First, import the TaskList
class from the views.py
module.
from .views import home, TaskList
Code language: Python (python)
Second, define tasks/
URL that displays the task list:
path('tasks/', TaskList.as_view(),name='tasks'),
Code language: Python (python)
In this code, we map the URL tasks/
to the result of the as_view()
method of the TaskList
class.
Note that you can specify the attributes of the TaskList
class in the as_view()
method. For example, you can pass a template name to the as_view()
method as follows:
path('tasks/', TaskList.as_view(template_name='mytodo.html'),name='tasks'),
Code language: Python (python)
The as_view()
method has arguments which are corresponding to the attributes of the TaskList
class.
Creating a Django ListView template #
Define the task_list.html
in the templates/todo
directory of the Todo
app:
{%extends 'base.html'%} {%block content%} <div class="center"> <h2>My Todo List</h2> {% if tasks %} <ul class="tasks"> {% for task in tasks %} <li><a href="#" class="{% if task.completed%}completed{%endif%}">{{ task.title }}</a> <div class="task-controls"> <a href="#"><i class="bi bi-trash"></i> </a> <a href="#"><i class="bi bi-pencil-square"></i></a> </div> </li> {% endfor %} {% else %} <p>? Yay, you have no pending tasks!</p> {% endif %} </ul> </div> {%endblock content%}
Code language: HTML, XML (xml)
The task_list.html
template extends the base.html
template of the project. In the task_list.html
template, we iterate over the tasks
QuerySet
and display each of them as an item on a list.
Also, we add the completed
CSS class to the a
tag if the task is completed. This CSS class will add a line-through to the item.
If the tasks
QuerySet
is empty, we display a message saying that there are no pending tasks.
Including ListView link in the base template #
Modify the base.html
template to include the My Tasks
link in the navigation:
{%load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="{% static 'css/style.css' %}" /> <title>Todo List</title> </head> <body> <header class="header"> <div class="container"> <a href="{%url 'home'%}" class="logo">Todo</a> <nav class="nav"> <a href="{%url 'home'%}"><i class="bi bi-house-fill"></i> Home</a> <a href="{% url 'tasks' %}"><i class="bi bi-list-task"></i> My Tasks</a> </nav> </div> </header> <main> <div class="container"> {%block content %} {%endblock content%} </div> </main> <footer class="footer"> <div class="container"> <p>© Copyright {% now "Y" %} by <a href="https://www.pythontutorial.net">Python Tutorial</a></p> </div> </footer> </body> </html>
Code language: HTML, XML (xml)
If you open the URL:
http://128.0.0.1:8000/tasks/
Code language: Python (python)
you’ll see the task list as follows:

You can download the final code for this Django ListView tutorial here.
Summary #
- Create a class-based view that displays a list of objects by inheriting from the
ListView
class.