Lesson 51 of 55 · Python
Project: Building a Todo App
Duration: 30 minutes
Lesson 51 of 55 · Python
Duration: 30 minutes
tasks table with columns id (INTEGER PK) and description (TEXT).\n3. Define routes to list tasks, add a new task, and delete a task.\n4. Render the UI using a simple Jinja2 template (templates/index.html).\n5. (Optional) Add a bit of CSS for a cleaner look.\n\n## Starter Skeleton\npython\nfrom flask import Flask, render_template, request, redirect, url_for\nimport sqlite3\n\napp = Flask(__name__)\n\ndef get_db():\n conn = sqlite3.connect('todo.db')\n conn.row_factory = sqlite3.Row # Access columns by name\n return conn\n\n# Initialise the DB (run once)\ndef init_db():\n with get_db() as db:\n db.execute('CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY, description TEXT NOT NULL)')\n\n@app.route('/')\ndef index():\n db = get_db()\n tasks = db.execute('SELECT * FROM tasks').fetchall()\n return render_template('index.html', tasks=tasks)\n\n@app.route('/add', methods=['POST'])\ndef add_task():\n desc = request.form['description']\n if desc:\n db = get_db()\n db.execute('INSERT INTO tasks (description) VALUES (?)', (desc,))\n db.commit()\n return redirect(url_for('index'))\n\n@app.route('/delete/<int:task_id>', methods=['POST'])\ndef delete_task(task_id):\n db = get_db()\n db.execute('DELETE FROM tasks WHERE id = ?', (task_id,))\n db.commit()\n return redirect(url_for('index'))\n\nif __name__ == '__main__':\n init_db()\n app.run(debug=True)\n\n\n## templates/index.html (very simple)\nhtml\n<!doctype html>\n<html lang="en">\n<head>\n <meta charset="utf-8">\n <title>Todo App</title>\n</head>\n<body>\n <h1>My Todo List</h1>\n <form action="{{ url_for('add_task') }}" method="post">\n <input type="text" name="description" placeholder="New task" required>\n <button type="submit">Add</button>\n </form>\n <ul>\n {% for task in tasks %}\n <li>\n {{ task['description'] }}\n <form action="{{ url_for('delete_task', task_id=task['id']) }}" method="post" style="display:inline;">\n <button type="submit">Delete</button>\n </form>\n </li>\n {% else %}\n <li>No tasks yet!</li>\n {% endfor %}\n </ul>\n</body>\n</html>\n\n\nRun the app, open http://127.0.0.1:5000/ in your browser, and start adding and removing tasks. This project ties together Flask routing, SQLite CRUD, Jinja2 templating, and form handling. Happy coding! 🎉\n