开发者新手进阶:纯手工用Python+Flask从零搭建个人任务管理系统并实现数据导出功能
🤖AI摘要
本文介绍如何用Python和Flask搭建个人任务管理系统。通过纯手工编码,无需外部工具,掌握核心技能如路由、数据库操作、模板渲染和文件下载。项目包括任务列表、添加/完成/删除任务以及数据导出功能。教程从环境准备、数据库设计到完整代码,帮助开发者快速掌握Flask实战应用。
为什么新手要手把手搭建这个项目
个人任务管理系统是开发者入门Flask最实用的实战项目。它能让你同时掌握路由、数据库操作、模板渲染和文件下载等核心技能,而且项目完成后可以直接用于日常工作管理。相比直接用Todoist或Notion,自己搭建的系统更灵活,还能自定义数据导出功能。本文全程纯手工编码,不用任何脚手架或生成器,确保每行代码都来自你的键盘。
整个项目使用Python 3.10+、Flask 3.0+和内置sqlite3模块,无需额外付费数据库。最终效果:浏览器访问localhost:5000,看到任务列表、添加表单、完成/删除按钮,以及“导出CSV”链接,一键下载所有任务数据。
一、环境准备(5分钟搞定)
- 确保电脑已安装Python 3.10或更高版本(官网下载即可)。
- 新建项目文件夹:
mkdir task_manager cd task_manager - 创建虚拟环境并激活(强烈推荐,避免全局污染):
- Windows:
python -m venv venv然后venv\Scripts\activate - Mac/Linux:
python3 -m venv venv然后source venv/bin/activate
- Windows:
- 安装唯一依赖:
pip install flask - 项目结构提前准备好:
task_manager/ ├── app.py ├── templates/ │ └── index.html └── tasks.db (运行后自动生成)二、数据库设计与初始化
任务表字段设计得简单实用:
- id:自增主键
- title:任务标题(必填)
- description:详细描述
- status:状态(未完成/已完成)
- due_date:截止日期(格式YYYY-MM-DD)
在app.py最上方写入初始化函数:import sqlite3 from flask import Flask, render_template, request, redirect, url_for, Response import io import csv app = Flask(__name__) def init_db(): conn = sqlite3.connect('tasks.db') c = conn.cursor() c.execute(''' CREATE TABLE IF NOT EXISTS tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, description TEXT, status TEXT DEFAULT '未完成', due_date TEXT ) ''') conn.commit() conn.close() # 启动时自动初始化 if __name__ == '__main__': init_db()三、核心路由与业务逻辑(app.py完整代码)
把下面完整代码复制到app.py(已包含所有功能):
# ...(上面init_db和app定义保持不变) def get_all_tasks(): conn = sqlite3.connect('tasks.db') c = conn.cursor() c.execute("SELECT * FROM tasks ORDER BY due_date") tasks = c.fetchall() conn.close() return tasks @app.route('/') def index(): tasks = get_all_tasks() return render_template('index.html', tasks=tasks) @app.route('/add', methods=['POST']) def add_task(): title = request.form['title'] description = request.form.get('description', '') due_date = request.form.get('due_date', '') conn = sqlite3.connect('tasks.db') c = conn.cursor() c.execute("INSERT INTO tasks (title, description, due_date) VALUES (?, ?, ?)", (title, description, due_date)) conn.commit() conn.close() return redirect(url_for('index')) @app.route('/complete/<int:task_id>') def complete_task(task_id): conn = sqlite3.connect('tasks.db') c = conn.cursor() c.execute("UPDATE tasks SET status='已完成' WHERE id=?", (task_id,)) conn.commit() conn.close() return redirect(url_for('index')) @app.route('/delete/<int:task_id>') def delete_task(task_id): conn = sqlite3.connect('tasks.db') c = conn.cursor() c.execute("DELETE FROM tasks WHERE id=?", (task_id,)) conn.commit() conn.close() return redirect(url_for('index')) @app.route('/export') def export_tasks(): tasks = get_all_tasks() output = io.StringIO() writer = csv.writer(output) writer.writerow(['ID', '标题', '描述', '状态', '截止日期']) for task in tasks: writer.writerow(task) output.seek(0) return Response( output.getvalue(), mimetype='text/csv', headers={ "Content-Disposition": "attachment; filename=tasks_export.csv" } ) if __name__ == '__main__': init_db() app.run(debug=True)重点说明:
/路由渲染首页并传递任务列表/add处理表单提交/complete/<id>和/delete/<id>用GET简化新手操作(生产环境可改POST+CSRF)/export核心数据导出功能:用csv模块生成内存文件,直接浏览器下载,无需保存本地临时文件四、前端模板编写(templates/index.html)
新建templates文件夹,然后创建index.html,复制以下代码(已集成Bootstrap CDN,美观又零配置):
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>我的任务管理系统</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body class="container mt-5"> <h1 class="mb-4">个人任务管理系统</h1> <!-- 添加任务表单 --> <form method="post" action="/add" class="mb-5"> <div class="row"> <div class="col-md-4"> <input type="text" name="title" class="form-control" placeholder="任务标题" required> </div> <div class="col-md-4"> <input type="text" name="description" class="form-control" placeholder="详细描述"> </div> <div class="col-md-3"> <input type="date" name="due_date" class="form-control"> </div> <div class="col-md-1"> <button type="submit" class="btn btn-primary w-100">添加</button> </div> </div> </form> <!-- 任务列表 --> <table class="table table-hover"> <thead class="table-light"> <tr> <th>ID</th> <th>标题</th> <th>描述</th> <th>状态</th> <th>截止日期</th> <th>操作</th> </tr> </thead> <tbody> {% for task in tasks %} <tr> <td>{{ task[0] }}</td> <td>{{ task[1] }}</td> <td>{{ task[2] }}</td> <td> {% if task[3] == '已完成' %} <span class="badge bg-success">已完成</span> {% else %} <span class="badge bg-warning">未完成</span> {% endif %} </td> <td>{{ task[4] }}</td> <td> <a href="/complete/{{ task[0] }}" class="btn btn-sm btn-success">完成</a> <a href="/delete/{{ task[0] }}" class="btn btn-sm btn-danger" onclick="return confirm('确定删除?')">删除</a> </td> </tr> {% endfor %} </tbody> </table> <!-- 数据导出按钮 --> <div class="text-center mt-4"> <a href="/export" class="btn btn-info btn-lg">一键导出CSV数据</a> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> </body> </html>Jinja2模板语法简单,新手一看就懂。表格自动循环显示所有任务,导出按钮直接指向/export路由。
五、运行与测试全流程
- 在项目根目录执行
python app.py - 浏览器打开 http://127.0.0.1:5000
- 添加几条任务,点击“完成”“删除”验证CRUD
- 点击“一键导出CSV数据”,浏览器自动下载tasks_export.csv,打开后数据整齐排列(支持Excel直接导入)
常见问题排查:- 数据库没生成?重启app.py即可(init_db会自动创建)
- 表单提交失败?检查字段name属性是否与代码一致
- CSV中文乱码?Flask Response已默认UTF-8,无需额外处理
六、进阶优化建议(适合站长和运维)
- 想加登录功能?后续接入Flask-Login即可
- 部署到服务器?用Gunicorn + Nginx,或直接扔到阿里云/腾讯云免费实例
- 数据导出改Excel?把csv换成pandas(pip install pandas openpyxl),几行代码搞定
- SEO优化:把系统部署成个人工具站,标题带“任务管理系统在线版”,流量自然来
通过这个纯手工项目,你已经掌握了Flask从零到一的完整链路。把代码保存好,下次直接复用模板,就能快速开发其他管理系统。建议每天花30分钟优化一个功能,坚持一周,你会发现自己已经从新手变成能独立交付Web项目的开发者。
