1. Django - Todo App
In this Challenge, you are supposed to create a Todo App using Django, that should allow the users to add tasks and mark as completed
Steps to complete the challenge:
- Click Run --> Install option from the project menu to install all required libraries.
- Click Run --> Run to run your application
- Click Run --> Open Preview, to view the running application.
- Click Run tests to test your application and click Submit to end the test.
MODEL:
It will have one table Todo, with the following fields and data types
- name - CharField
- task - CharField
- completed - BooleanField
Create the following endpoints with functionalities as per the instructions below:
'
/' - This endpoint should render the home page of the app and it is used to add the tasksInput fields user name and task
Response: Should display the alert message after the task is added as given in the image below

'
task_view/' - This endpoints should show the list of tasks added to the database and Create a button for the each task to switch and mark the task as "Completed and Not Completed(default value)\". If no task is added, it should display the message NO TASKS HERE.Refer the image given below
Note: Create a common Navigation bar for the both the pages, nav bar should have the following elements and redirect to the corresponding pages
Todo --> Home Page - '/'
View Tasks --> View Tasks - '/task_view'

'
cross/<id>/' - Used to mark the task as completed and strike the task'
uncross/<id>/' - Used to mark the task as not completed and remove the strike
Software Instructions
This question requires Python 2 and Django 1.11.5.
Install Python and Django
Git Instructions
Use the following commands to work with this project
Run
python3 manage.py makemigrations; python3 manage.py migrate --run-syncdb; python3 manage.py runserver 0.0.0.0:8000Test
py.test -v taskTodo/test_case.py --junitxml=\"result.xml\"Install
python3 -m pip install --user --upgrade pip; pip3 install --user pytest django pytest-django
Solution
taskTodo/models.py
from django.db import models
# Create your models here.
class Todo(models.Model):
name = models.CharField(max_length=255)
task = models.CharField(max_length=255)
completed = models.BooleanField(default=False)
taskTodo/admin.py
from django.contrib import admin
from .models import Todo
# Register your models here.
class TodoAdmin(admin.ModelAdmin):
pass
admin.site.register(Todo, TodoAdmin)
taskTodo/views.py
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .models import Todo
from django.contrib import messages
# Create your views here.
def index(request):
if request.method == "GET":
return render(request, "index.jinja")
if request.method == "POST":
try:
name = request.POST.get("name")
task = request.POST.get("task")
todo = Todo(name=name, task=task)
todo.save()
messages.add_message(request, messages.SUCCESS, "Task added successfully")
except:
messages.add_message(request, messages.ERROR, "Something went wrong")
return HttpResponseRedirect("/")
return HttpResponse("Method not allowed", status=405)
def task_view(request):
if request.method == "GET":
todos = Todo.objects.all()
context = {"todos": todos}
return render(request, "task_view.jinja", context)
return HttpResponse("Method not allowed", status=405)
def cross_task(request, id):
if request.method == "POST":
try:
todo = Todo.objects.get(id=id)
todo.completed = True
todo.save()
messages.add_message(request, messages.SUCCESS, "Task updated successfully")
except:
messages.add_message(request, messages.ERROR, "Something went wrong")
return HttpResponseRedirect("/task_view")
return HttpResponse("Method not allowed", status=405)
def uncross_task(request, id):
if request.method == "POST":
try:
todo = Todo.objects.get(id=id)
todo.completed = False
todo.save()
messages.add_message(request, messages.SUCCESS, "Task updated successfully")
except:
messages.add_message(request, messages.ERROR, "Something went wrong")
return HttpResponseRedirect("/task_view")
return HttpResponse("Method not allowed", status=405)
todoApp/urls.py
from django.contrib import admin
from django.urls import path, include
from taskTodo import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),
path('task_view/', views.task_view, name='task_view'),
path('cross/<int:id>/', views.cross_task, name='cross_task'),
path('uncross/<int:id>/', views.uncross_task, name='uncross_task'),
]
todoApp/templates/layout.jinja
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}Django ToDo{% endblock title %}</title>
<link rel="stylesheet" href="https://bootswatch.com/5/brite/bootstrap.min.css" />
</head>
<body class="bg-light">
<header>
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">Todo</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/task_view">View Tasks</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main class="container-fluid">
{% block content %}{% endblock content %}
</main>
<footer></footer>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/js/bootstrap.bundle.min.js"
integrity="sha384-k6d4wzSIapyDyv1kpU366/PK5hCdSbCRGRCMv+eplOQJWyd1fbcAu9OCUj5zNLiq"
crossorigin="anonymous"
></script>
{% block scripts %}
{% endblock scripts %}
</body>
</html>
todoApp/templates/index.jinja
{% extends "layout.jinja" %}
{% block content %}
<div class="container-fluid py-4 bg-white">
<h1 class="text-center">Add your Tasks below</h1>
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert">
{{ message }}
</div>
{% endfor %}
<form action="/" class="mx-auto" style="max-width: 20rem;" method="POST">
{% csrf_token %}
<div class="mb-3">
<label class="form-label" for="name">User:</label>
<input class="form-control" type="text" name="name">
</div>
<div class="mb-3">
<label class="form-label" for="task">Task:</label>
<input class="form-control" type="text" name="task">
</div>
<button class="d-block btn btn-success mx-auto" type="submit">Add Task</button>
</form>
</div>
{% endblock content %}
todoApp/templates/task_view.jinja
{% extends "layout.jinja" %}
{% block content %}
<div class="container-fluid py-4 bg-white">
<h1 class="text-center">List of Tasks</h1>
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert">
{{ message }}
</div>
{% endfor %}
<table class="table mx-auto" style="max-width: 40rem; width: 100%;">
<thead>
<tr>
<th scope="col">User Name</th>
<th scope="col">Task</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
{% for todo in todos %}
<tr>
<td>{{ todo.name }}</td>
<td class="{%if todo.completed %}text-success text-decoration-line-through{%endif%}">{{ todo.task }}
</td>
<td>
{%if todo.completed %}
<form action="/uncross/{{ todo.id }}/" class="d-inline" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-link">Completed</button>
</form>
{%else%}
<form action="/cross/{{ todo.id }}/" class="d-inline" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-link">Not Completed</button>
</form>
{%endif%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock content %}
todoApp/settings.py
...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
"templates"
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
...