Create a To-Do Web App with Flask


Creating a To-Do Web App with Flask

Creating a To-Do Web App with Flask is a great way to practice building web applications using Python. The app will allow users to add, view, edit, and delete tasks. We'll be using Flask for the backend and HTML/CSS for the frontend.

Steps to Build a Simple To-Do Web App Using Flask

Step 1: Install Flask

First, ensure that Flask is installed in your Python environment. If not, you can install it using pip:

pip install flask

Step 2: Set Up Your Project Structure

Create a folder structure for your project like this:

todo-app/
│
├── app.py            # Flask application
├── templates/        # HTML templates
│   ├── index.html    # Main page
│   ├── edit.html     # Edit task page
└── static/           # Static files (CSS, JS, etc.)
    └── styles.css    # Styling

Step 3: Set Up the Flask App

app.py: This is the main Flask application file.

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# Sample data for tasks (In a real app, you'd use a database)
tasks = [
    {"id": 1, "title": "Buy groceries", "done": False},
    {"id": 2, "title": "Finish homework", "done": False},
]

# Home route to show all tasks
@app.route('/')
def index():
    return render_template('index.html', tasks=tasks)

# Route to add a new task
@app.route('/add', methods=['POST'])
def add_task():
    title = request.form.get('title')
    if title:
        new_task = {
            "id": len(tasks) + 1,
            "title": title,
            "done": False
        }
        tasks.append(new_task)
    return redirect(url_for('index'))

# Route to mark a task as done
@app.route('/done/')
def mark_done(task_id):
    task = next((t for t in tasks if t["id"] == task_id), None)
    if task:
        task["done"] = True
    return redirect(url_for('index'))

# Route to delete a task
@app.route('/delete/')
def delete_task(task_id):
    global tasks
    tasks = [task for task in tasks if task["id"] != task_id]
    return redirect(url_for('index'))

# Route to edit a task
@app.route('/edit/', methods=['GET', 'POST'])
def edit_task(task_id):
    task = next((t for t in tasks if t["id"] == task_id), None)
    if request.method == 'POST':
        task['title'] = request.form['title']
        return redirect(url_for('index'))
    return render_template('edit.html', task=task)

if __name__ == '__main__':
    app.run(debug=True)
Explanation:
  • Home Route (/): Displays all tasks.
  • Add Route (/add): Adds a new task to the list.
  • Done Route (/done/<task_id>): Marks a task as completed.
  • Delete Route (/delete/<task_id>): Deletes a task.
  • Edit Route (/edit/<task_id>): Allows editing a task's title.

Step 4: Create HTML Templates

index.html (Home page for displaying tasks)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-Do App</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>

    <h1>To-Do List</h1>

    <form action="/add" method="POST">
        <input type="text" name="title" placeholder="Enter task" required>
        <button type="submit">Add Task</button>
    </form>

    <ul>
        {% for task in tasks %}
            <li>
                <span style="text-decoration: {{ 'line-through' if task.done else 'none' }}">{{ task.title }}</span>
                {% if not task.done %}
                    <a href="{{ url_for('mark_done', task_id=task.id) }}">Mark as done</a>
                {% endif %}
                <a href="{{ url_for('delete_task', task_id=task.id) }}" style="color: red;">Delete</a>
                <a href="{{ url_for('edit_task', task_id=task.id) }}">Edit</a>
            </li>
        {% endfor %}
    </ul>

</body>
</html>

edit.html (Edit page for a specific task)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Edit Task</title>
</head>
<body>

    <h1>Edit Task</h1>
    <form action="" method="POST">
        <input type="text" name="title" value="{{ task.title }}" required>
        <button type="submit">Save Changes</button>
    </form>

    <a href="{{ url_for('index') }}">Back to Home</a>

</body>
</html>

Step 5: Create Static Files (CSS)

styles.css (Basic styling for the app)

body {
    font-family: Arial, sans-serif;
    text-align: center;
}

h1 {
    color: #4CAF50;
}

form {
    margin-bottom: 20px;
}

input[type="text"] {
    padding: 10px;
    font-size: 14px;
}

button {
    padding: 10px 20px;
    font-size: 14px;
    background-color: #4CAF50;
    color: white;
    border: none;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

ul {
    list-style-type: none;
}

ul li {
    margin: 10px 0;
}

a {
    margin: 0 10px;
    text-decoration: none;
    color: #2196F3;
}

a:hover {
    text-decoration: underline;
}

a[style="color: red;"] {
    color: red;
}

Step 6: Running the Flask App

Now, run the Flask application using:

python app.py

Your app will be available at http://127.0.0.1:5000/.

Step 7: Final Notes

  • Adding Database Support: This app currently uses a Python list to store tasks, which is not persistent. You can integrate SQLite or MySQL for a more robust solution.
  • Enhancements: You can enhance the app by adding user authentication, prioritizing tasks, or even adding deadlines.

With this Flask To-Do Web App, you have learned how to work with web forms, routes, templates, and basic CRUD operations. Feel free to extend the app by adding more features like due dates or notifications!