目录结构(最终)
taskmaster/
│
├── app.py ← 主程序入口
│
├── templates/ ← 页面模板(HTML)
│ ├── base.html ← 基础模板
│ ├── index.html ← 主页面:显示 + 添加任务
│ └── update.html ← 修改任务页面
│
├── static/
│ └── css/
│ └── main.css ← 页面样式
│
└── test.db ← SQLite 数据库(执行后自动生成)
🛠 第一步:创建基本 Flask 应用
📄 文件:app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug=True)
🔍 说明:
- 启动 Flask 项目
- 设置主页路由
/ - 关联
index.html模板
✅ 功能结果:访问 http://127.0.0.1:5000/ 可看到网页
🎨 第二步:创建模板页面(templates 文件夹)
📄 文件:templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
🔍 说明:
- 模板继承母版
- 所有页面都继承它,避免重复写结构
📄 文件:templates/index.html
{% extends 'base.html' %}
{% block body %}
<div class="form">
<form action="/" method="POST">
<input type="text" name="content" id="content">
<input type="submit" value="Add Task">
</form>
</div>
<table>
<tr>
<th>Task</th>
<th>Created</th>
<th>Actions</th>
</tr>
{% for task in tasks %}
<tr>
<td>{{ task.content }}</td>
<td>{{ task.date_created }}</td>
<td>
<a href="/delete/{{ task.id }}">Delete</a>
<a href="/update/{{ task.id }}">Update</a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
🧩 第三步:连接数据库(Flask-SQLAlchemy)
📄 修改:app.py
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from flask import request, redirect
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
✅ 模型定义:Todo 类
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
completed = db.Column(db.Integer, default=0)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Task %r>' % self.id
💡 功能说明:
- 数据表结构
db.create_all()会根据这个类生成test.db文件
🛠 第四步:任务增删改查功能(CRUD)
🟢 显示任务 + 添加任务
@app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'POST':
task_content = request.form['content']
new_task = Todo(content=task_content)
try:
db.session.add(new_task)
db.session.commit()
return redirect('/')
except:
return 'Error adding task'
else:
tasks = Todo.query.order_by(Todo.date_created).all()
return render_template('index.html', tasks=tasks)
🔴 删除任务
@app.route('/delete/<int:id>')
def delete(id):
task_to_delete = Todo.query.get_or_404(id)
try:
db.session.delete(task_to_delete)
db.session.commit()
return redirect('/')
except:
return "Error deleting task"
🟡 修改任务
📄 文件:templates/update.html
{% extends 'base.html' %}
{% block body %}
<h1 style="text-align:center">Update Task</h1>
<div class="form">
<form action="/update/{{ task.id }}" method="POST">
<input type="text" name="content" id="content" value="{{ task.content }}">
<input type="submit" value="Update Task">
</form>
</div>
{% endblock %}
📄 修改 app.py 路由:
python
复制编辑
@app.route('/update/<int:id>', methods=['GET', 'POST'])
def update(id):
task = Todo.query.get_or_404(id)
if request.method == 'POST':
task.content = request.form['content']
try:
db.session.commit()
return redirect('/')
except:
return 'Error updating task'
else:
return render_template('update.html', task=task)
💄 第五步:样式文件(可选)
📄 文件:static/css/main.css
body {
font-family: sans-serif;
background-color: #f5f5f5;
}
.form {
text-align: center;
margin-top: 30px;
}
table {
margin: auto;
border-collapse: collapse;
}
td, th {
border: 1px solid #ccc;
padding: 10px 20px;
}
✅ 最终功能对应图表:
| 页面 | 功能 | 后端处理 | 模板变量 |
|---|---|---|---|
/ (GET) | 显示任务列表 | Todo.query.all() | tasks |
/ (POST) | 添加任务 | db.session.add() | — |
/delete/<id> | 删除任务 | db.session.delete() | — |
/update/<id> (GET) | 展示原内容 | Todo.query.get_or_404() | task |
/update/<id> (POST) | 修改任务 | task.content = ... | — |
🧠 调试命令提示:
python
>>> from app import db
>>> db.create_all() # 创建数据库表
>>> Todo.query.all() # 查看所有任务
💬 常见报错排查:
| 错误现象 | 原因 | 解决办法 |
|---|---|---|
| 404 Not Found | /delete/<id> 无效 | 检查是否传入正确 id |
| 提交没反应 | 表单没写 method="POST" | 检查 <form> 标签 |
| 数据不显示 | 没传 tasks 到模板 | 检查 render_template(..., tasks=tasks) |
| 数据库无反应 | 忘记 db.create_all() | 终端运行一次 |