求助:如何在PyCharm中构建带价格存储的类Google Keep风格Flask待办清单
Google Keep风格待办清单Flask实现方案
1. 项目初始化与依赖安装
先搭建基础环境,安装必要依赖:
# 创建并激活虚拟环境(可选但推荐) python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 安装依赖 pip install flask flask-sqlalchemy
2. 数据库模型设计
用SQLAlchemy定义待办项模型,包含核心字段:内容、价格、完成状态:
from flask import Flask, render_template, request, redirect from flask_sqlalchemy import SQLAlchemy from datetime import datetime app = Flask(__name__) # 用SQLite做轻量数据库,生产环境可替换为MySQL/PostgreSQL app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todos.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class Todo(db.Model): id = db.Column(db.Integer, primary_key=True) content = db.Column(db.String(200), nullable=False) price = db.Column(db.Float, nullable=False) is_completed = db.Column(db.Boolean, default=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) def __repr__(self): return f'<Todo {self.id}>' # 创建数据库表(首次运行时执行) with app.app_context(): db.create_all()
3. Flask核心业务逻辑
实现待办项的增删改查核心接口:
# 首页展示所有待办 @app.route('/') def index(): todos = Todo.query.order_by(Todo.created_at.desc()).all() return render_template('index.html', todos=todos) # 添加新待办 @app.route('/add', methods=['POST']) def add_todo(): content = request.form.get('content') price = request.form.get('price') if content and price: try: price = float(price) if price >= 0: new_todo = Todo(content=content, price=price) db.session.add(new_todo) db.session.commit() except ValueError: # 处理价格非数字的情况,可前端提前做校验 pass return redirect('/') # 切换待办完成状态 @app.route('/toggle/<int:todo_id>') def toggle_completed(todo_id): todo = Todo.query.get_or_404(todo_id) todo.is_completed = not todo.is_completed db.session.commit() return redirect('/') # 删除待办 @app.route('/delete/<int:todo_id>') def delete_todo(todo_id): todo = Todo.query.get_or_404(todo_id) db.session.delete(todo) db.session.commit() return redirect('/') if __name__ == '__main__': app.run(debug=True)
4. Google Keep风格前端实现
创建templates/index.html,用纯CSS实现Google Keep的勾选框样式,无需额外JS:
<!DOCTYPE html> <html> <head> <title>Keep风格待办清单</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; } body { background-color: #f5f5f5; padding: 20px; } .container { max-width: 600px; margin: 0 auto; } h1 { color: #333; margin-bottom: 20px; } .add-form { display: flex; gap: 10px; margin-bottom: 25px; } .add-form input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; } .add-form button { padding: 10px 20px; background-color: #4285f4; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } .todo-item { display: flex; align-items: center; background: white; padding: 12px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-bottom: 10px; } .checkbox { width: 22px; height: 22px; border: 2px solid #999; border-radius: 50%; margin-right: 12px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; text-decoration: none; } .checkbox.completed { background-color: #34a853; border-color: #34a853; } .checkbox.completed::after { content: '✓'; color: white; font-weight: bold; font-size: 14px; } .todo-content { flex: 1; font-size: 16px; color: #333; } .todo-content.completed { text-decoration: line-through; color: #999; } .todo-price { margin-left: 15px; color: #666; font-size: 14px; } .delete-btn { margin-left: 15px; color: #ea4335; text-decoration: none; font-size: 14px; } </style> </head> <body> <div class="container"> <h1>我的待办清单</h1> <form class="add-form" action="/add" method="POST"> <input type="text" name="content" placeholder="输入待办内容" required> <input type="number" name="price" placeholder="输入价格" step="0.01" min="0" required> <button type="submit">添加</button> </form> {% for todo in todos %} <div class="todo-item"> <a href="/toggle/{{ todo.id }}" class="checkbox {% if todo.is_completed %}completed{% endif %}"></a> <div class="todo-content {% if todo.is_completed %}completed{% endif %}">{{ todo.content }}</div> <div class="todo-price">¥{{ "%.2f"|format(todo.price) }}</div> <a href="/delete/{{ todo.id }}" class="delete-btn">删除</a> </div> {% endfor %} </div> </body> </html>
5. 运行项目
在项目根目录执行:
python app.py
访问http://localhost:5000即可使用,勾选框点击后会切换完成状态,同时内容划横线,完全匹配Google Keep的视觉风格。
内容的提问来源于stack exchange,提问作者Lucy Sunday
相关产品推荐
相关产品推荐

