Showing posts with label 72110. Show all posts
Showing posts with label 72110. Show all posts

Python FSP - Mini-Project - Sprint4- Python Django || Fresco Play || 72110

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 tasks

    Input 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:8000
    
  • Test

     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',
            ],
        },
    },
]
...
Share: