Skip to main content

Todo app

Now let's create slightly more advanced a To Do List app. We can create the app by:

python3 manage.py startapp todo

Register the app in our main django application myWebApp/settings.py

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

# my apps
'hello',
'today',
'todo',
]

Register the url in myWebApp/urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', include('hello.urls')),
path('today/', include("today.urls")),
path('todo/', include('todo.urls')),
]

Our todo urls does not exist yet, so let's create todo/urls.py with following content:

from django.urls import path
from . import views

urlpatterns = [
path('', views.index, name='index'),
]

Write index function in todo/views.py:

from django.shortcuts import render

# Create your views here.

todo = ["item1", "item2", "item3"]

def index(request):
return render(request, 'todo/index.html', {
'todo': todo
})

Crete our todo/templates/todo/index.html page:

<html>
<head>
<title>To Do App</title>
</head>
<body>
<ul>
{% for item in todo %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>

Now we can python3 manage.py runserver and check http://localhost:8000/todo/

Let's add the functionality to add todo items. Write a new view function:

def addtodo(request):
return render(request, 'todo/add.html')

Include it in our todo/urls.py:

from django.urls import path
from . import views

app_name = 'todo'

urlpatterns = [
path('', views.index, name='index'),
path('add', views.addtodo, name='addtodo'),
]

Create todo/templates/todo/add.html:

<html>
< head>
<title>Todo app</title>
< /head>
<body>
<h3>Add To Do Item</h3>
<form>
<input type="text" name="todo">
<input type="submit">
</form>
</body>
</html>

Our add.html and index.html are very similar except the body part. We can use templates in such cases. Create todo/templates/base.html:

<html>
<head>
<title>Todo app</title>
</head>
<body>
{% block bodycontent %}
{% endblock %}
</body>
</html>

Rewrite our index.html:

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

{% block bodycontent %}
<h1>To Do List</h1>
<ul>
{% for item in todo %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<a href="{% url 'todo:addtodo' %}">Add To Do</a>
{% endblock %}

Rewrite our add.html:

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

{% block bodycontent %}
<h3>Add To Do Item</h3>
<form>
<input type="text" name="todo">
<input type="submit">
</form>
<a href="{% url 'todo:index' %}">Go back to To Do list</a>
{% endblock %}

Instead of using html forms, we can use Django form. Modify todo/vies.py:

from django.shortcuts import render
from django import forms

# Create your views here.

todo = ["item1", "item2", "item3"]

class AddTodo(forms.Form):
AddTodo = forms.CharField(label="Add To do")

def index(request):
return render(request, 'todo/index.html', {
'todo': todo
})

def addtodo(request):
return render(request, 'todo/add.html', {
"form": AddTodo
})
{% extends 'todo/base.html' %}

{% block bodycontent %}
<h3>Add To Do Item</h3>
<form action="{% url 'todo:addtodo' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
<a href="{% url 'todo:index' %}">Go back to To Do list</a>
{% endblock %}

We have to add the ability to add the tasks:

from django.shortcuts import render
from django import forms
from django.http import HttpResponseRedirect
from django.urls import reverse

todo = ["item1", "item2", "item3"]

class AddTodo(forms.Form):
AddTodo = forms.CharField(label="Add To do")

def index(request):
return render(request, 'todo/index.html', {
'todo': todo
})

def addtodo(request):
if request.method == "POST":
form = AddTodo(request.POST)
if form.is_valid():
new_todo = form.clean_data['AddTodo']
todo.append(new_todo)
return HttpResponseRedirect(reverse("todo:index"))
else:
return render(request, 'todo/add.html', {
"form": form
})

return render(request, 'todo/add.html', {
"form": AddTodo
})