Django Tutorial For Todo Application
Building Blog application using Django
In this post we will build a Todo application using Django, before going through this application,
Let us create a directory to keep your code segregated
```bash
$ mkdir todo
$ cd todo
```
You need to have python and virtual environment installed
```bash
sudo apt-get install python3
sudo apt-get install python3-pip
sudo apt-get install python3-venv
```
Second let us create virtual environment
```bash
python3 -m venv venvtodo
```
Before we start with actual django project, we need to activate project creation
```bash
source venv/bin/activate
```
for windows use following command
```bash
venvtodo\Scripts\activate.bat
```
Install django
```bash
pip3 install Django
```
If you want to install specific version of Django, you can use following command
```bash
pip3 install Django==4.0.2
```
Start Project
```bash
django-admin startproject todo
cd todo
python3 manage.py runserver
```
if you want to run Django on differnt port
```bash
python manage.py runserver 9000
```
You will see following output on screen
```
python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
February 27, 2022 - 11:07:13
Django version 4.0.2, using settings 'todoapp.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK
```
and following will be visible in browser

Django project is split into apps. Each app handles specific tasks or function. Let us create a application for managing our todo list.
```bash
python3 manage.py startapp todoapp
```
Once app is created, it needs to be registered in settings.py
```python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todoapp',
]
```
urls.py is not created inside app directory, we need to create `todoapp\urls.py` manually.
```python
from django.urls import path
from . import views
app_name = 'todoapp'
urlpatterns = [
path('', views.index, name='index'),
]
```
To have application urls accessible from main project, we need to add this urls.py with main project
```python
from django.contrib import admin
from django.urls import include, path # Add include here
urlpatterns = [
path('admin/', admin.site.urls),
path('todo/', include('todoapp.urls')),# Add this line
]
```
Before doing further changes let us create sample view in `todoapp/views.py` we will edit this file later for more details but we need to create this view to avoid any error while running intermediate command.
```python
from django.shortcuts import render, get_object_or_404, redirect
def index(request):
context = "This is coming from view"
return render(request, 'todo/index.html',{'context':context})
```
create a tolder `templates` inside `todoapp` folder. Create subfolder `todo` inside `templates` folder.
You might be thinking why we need `todo` folder again inside templates folder. Well, when you run `runstatic` command, django will consolidate all templates, css and js files in projectwide central static folder. If you have multiple apps in your django project, there is possibility that template names may be common across projects e.g. `index.html`
Now when you run django project using `python3 manage.py runserver` you will see following error.

This is because we have not yet handled our base url, we have created an application which is server at `/todo`. If you keep this blank, you application will be server from base url.
# Creating Model
```python
from django.db import models
from django.utils import timezone
STATUS_CHOICES = (
('In progress','In progress'),
('On Hold', 'On Hold'),
('Cancelled','Cancelled'),
('Completed','Completed'),
)
# Create your models here.
class Task(models.Model):
task_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=350)
date_created = models.DateTimeField(default=timezone.now)
status = models.CharField(max_length=15, choices=STATUS_CHOICES, default='In progress')
date_completed = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.title
```
Once models.py file has been updated, you need to run `makemigrations` and `migrate` commandas as shown below.
```bash
python3 manage.py makemigrations
Migrations for 'todoapp':
todoapp\migrations\0001_initial.py
- Create model Task
```
```bash
python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, todoapp
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Applying todoapp.0001_initial... OK
```
You also need to create superuser.
```bash
python3 manage.py createsuperuser
```
You can login to `http://127.0.0.1:8000/admin` by using the ID created in previous command. To ensure the model created is visible to you, you need to add this model in admin.py in the `todoapp\admin.py`
```python
from django.contrib import admin
from .models import Task
# Register your models here.
admin.site.register(Task)
```
Once done, your admin screen will look like this.

Let us manually add tasks from admin screen.
Now we need to display these tasks `templates\todo\index.html`
```html
<h1> Task List</h1>
<ul>
{% for task in task_list %}
<li><a href="details/{{task.task_id}}"><p>Task Name : {{task.title}} </p></a></li>
{% endfor %}
</ul>
```

Let us also add details page to display task details `templates\todo\details.html`
```html
<h1> Task Details</h1>
<p>Task id : {{task.task_id}} </p>
<p>Task Title : {{task.title}} </p>
<p>Task Date Created : {{task.date_created}} </p>
<p>Task Status : {{task.status}} </p>
```
update `\todo\views.py`
```python
def details(request, task_id):
task = get_object_or_404(Task, task_id=task_id)
return render(request, 'todo/details.html',{'task':task})
```
updated `todoapp\urls.py`
```python
from django.urls import path
from . import views
app_name = 'todo'
urlpatterns = [
path('', views.index, name='index'),
path('details/<task_id>/', views.details, name='details'), #added this line
]
```
Once these changes are done, you can run the application and then can see more details when you click on hyperlink. Please note the change in url and `task_id` in url.

Hope this was helpful. Please let me know your feedback.
This post is written by Pravin
Share it :