To-do list applications are essential tools that improve our productivity and help us keep track of important tasks. In this tutorial, we will go through the steps involved in building a to-do list application using Django. Django is a high-level web framework that enables developers to build robust web applications quickly.
Prerequisites
It is assumed that you have prior knowledge of Python, Django, and HTML/CSS. If you are new to Django, you should take a look at the official Django Documentation to get started.
Setting up a new Django Project
First, we need to create a new Django project. Open your terminal and navigate to the directory where you want to create your project. Then run the following command:
django-admin startproject todo
The command above will create a new Django project named "todo." Once the project is created, navigate into the project directory by running:
cd todo
Next, create a new Django app for handling the to-do list application by running the following command:
python manage.py startapp todos
Creating the To-Do Model
The model is the backbone of a Django application. It defines the data structure for the application. In our case, we want to create a Todo
model that has the following fields:
title
A short description of the task.description
A detailed description of the task.completed
A checkbox that indicates if the task is completed or not.created_at
The date and time when the task was created.
Open the models.py
file inside the todos
app directory and define the Todo
model as follows:
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
The __str__
method is used to display the model's title in the Django admin panel.
Once you have defined the model, apply the migrations by running the following command:
python manage.py makemigrations
python manage.py migrate
Creating Views and Templates
Now that we have defined the model, we can create the views and templates for our to-do list application.
Open the views.py
file inside the todos
app directory and define the following views:
from django.shortcuts import render, redirect
from .models import Todo
def index(request):
todos = Todo.objects.order_by('-created_at') # get all todos ordered by newest to oldest
return render(request, 'todos/index.html', {'todos': todos})
def create(request):
if request.method == 'POST':
title = request.POST['title']
description = request.POST['description']
completed = False if not request.POST.get('completed', False) else True
Todo.objects.create(title=title, description=description, completed=completed)
return redirect('todos:index')
else:
return render(request, 'todos/create.html')
def update(request, id):
todo = Todo.objects.get(id=id)
if request.method == 'POST':
title = request.POST['title']
description = request.POST['description']
completed = False if not request.POST.get('completed', False) else True
todo.title = title
todo.description = description
todo.completed = completed
todo.save()
return redirect('todos:index')
else:
return render(request, 'todos/update.html', {'todo': todo})
def delete(request, id):
todo = Todo.objects.get(id=id)
todo.delete()
return redirect('todos:index')
The index
view retrieves all the Todo
objects from the database and orders them by the newest to oldest. The create
view creates a new Todo
object in the database while the update
view updates an existing Todo
object. The delete
view deletes a Todo
object from the database.
Next, create the templates inside the todos/templates/todos
directory as follows:
index.html
{% extends 'base.html' %}
{% block content %}
<h2>To-do List</h2>
<a href="{% url 'todos:create' %}" class="btn btn-primary">Add New</a>
<ul>
{% for todo in todos %}
<li>
<h4>{{ todo.title }}</h4>
<p>{{ todo.description }}</p>
{% if todo.completed %}
<p>Completed: Yes</p>
{% else %}
<p>Completed: No</p>
{% endif %}
<p>Created At: {{ todo.created_at }}</p>
<div class="btn-group" role="group">
<a href="{% url 'todos:update' todo.id %}" class="btn btn-secondary"><i class="fas fa-edit"></i></a>
<a href="{% url 'todos:delete' todo.id %}" class="btn btn-danger"><i class="fas fa-trash"></i></a>
</div>
</li>
{% empty %}
<h3>No todos</h3>
{% endfor %}
</ul>
{% endblock %}
create.html
{% extends 'base.html' %}
{% block content %}
<h2>Create New Todo</h2>
<form method="POST">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" name="title" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" name="description" required></textarea>
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="completed">
<label class="form-check-label" for="completed">Completed</label>
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
{% endblock %}
update.html
{% extends 'base.html' %}
{% block content %}
<h2>Update Todo</h2>
<form method="POST">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" name="title" value="{{ todo.title }}" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" name="description" required>{{ todo.description }}</textarea>
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="completed" {% if todo.completed %}checked {% endif %}>
<label class="form-check-label" for="completed">Completed</label>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
{% endblock %}
base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>To-do List</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-7gxyERfRjHmjZ/AzP9nUbP6I246U6xEGw6mvhJdMl2hNKoFq3sW8BvC1K/Rmd1hcKYgRLE+Sh8bKwIepnMCzvg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<div class="container mt-5">
{% block content %}
{% endblock %}
</div>
<!-- Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper-core.min.js" integrity="sha384-PXrm7r0ZtFcNlIoACWDgcQpwjKTA+vGyQdnbBoz3hG65sXsDvZjRdsiOokhTccWn" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.min.js" integrity="sha384-O7vZQNf2+j3oIZXsW9GjDrURlbfAdRnBLT50obdWgEQhPhv61erg+vjJzfdmX9BZ" crossorigin="anonymous"></script>
</body>
</html>
Registering the App
Now that we have created the views and templates, we need to register the app in the project's settings.py
file. Open the settings.py
file and add the following to the INSTALLED_APPS
list:
INSTALLED_APPS = [
# ...
'todos',
]
Hooking up the URLs
Finally, we need to add the URLs for our to-do list application. Open the urls.py
file inside the todos
app directory and add the following:
from django.urls import path
from . import views
app_name = 'todos'
urlpatterns = [
path('', views.index, name='index'),
path('create/', views.create, name='create'),
path('update/<int:id>/', views.update, name='update'),
path('delete/<int:id>/', views.delete, name='delete'),
]
The URLs above map the application views to their respective URLs.
Try it out
That's it! We have now created a to-do list application using Django. To test the application, run the development server by executing the following command:
python manage.py runserver
You can access the to-do list application by visiting http://localhost:8000/todos/
in your web browser.
Conclusion
In this tutorial, we went through the process of building a to-do list application using Django. We covered the creation of the model, views, and templates, as well as registering the app and hooking up the URLs.
This application is just a starting point, and there are many ways to extend and customize it. For example, you can add authentication, pagination, search functionality, or even deploy the application to the cloud for public use. Try experimenting with different features and learn more about Django to build more robust web applications!