太棒了!欢迎来到 【跟着AI学Python】第29天 —— 综合项目构思日!🎉经过前28天的学习,你已经掌握了:✅ 基础语法 ✅ 文件操作 ✅ 网络请求 ✅ 数据处理 ✅ Web开发(Flask) ✅ 可视化
现在,是时候整合所学,设计一个属于你自己的小项目了!
🌐 我的 Python 项目设计:简易博客系统(Flask 版)
1. 项目名称
MiniBlog —— 轻量级、无数据库、文件驱动的个人博客系统
2. 为什么做这个项目?
- ✅ 整合所学:Flask 路由 + Jinja2 模板 + JSON 文件存储 + 表单处理
- ✅ 为进阶打基础:后续可轻松升级为带用户登录、评论的完整博客
3. 核心功能(MVP 最小可用版本)
| |
|---|
| 首页展示 | |
| 文章详情页 | |
| 后台写文章 | |
| 本地存储 | 所有文章保存在 data/posts.json 中 |
| 自动摘要 | |
⚠️ 暂不实现(保持简单):用户登录、编辑/删除、分类、评论
4. 技术栈
✅ 优势:
5. 模块划分与文件结构
miniblog/├── app.py ← 主应用(路由 + 视图)├── data/│ └── posts.json ← 文章数据(自动生成)├── templates/│ ├── base.html ← 基础模板(含导航栏)│ ├── index.html ← 首页(文章列表)│ ├── post.html ← 文章详情页│ └── write.html ← 写文章表单页└── static/ └── style.css ← 简单样式(可选)
🔹 模块职责说明
| |
|---|
app.py | - 定义 /, /post/<id>, /write 路由- 处理表单提交- 读写 posts.json |
templates/base.html | |
templates/index.html | |
templates/post.html | |
templates/write.html | |
6. 数据格式设计(posts.json)
[ { "id": 1, "title": "欢迎来到 MiniBlog", "content": "这是第一篇文章...\n支持换行和段落。", "created_at": "2026-03-01 15:40" }, { "id": 2, "title": "如何使用本博客", "content": "点击右上角「写文章」即可发布新内容。", "created_at": "2026-03-01 15:42" }]
💡 ID 生成规则:每次新增文章 = 当前最大 ID + 1
7. 页面原型(文字版)
🏠 首页 (/)
MINIBLOG──────────────────────【写文章】← 右上角链接● 欢迎来到 MiniBlog (2026-03-01 15:40) 这是第一篇文章...支持换行和段落。● 如何使用本博客 (2026-03-01 15:42) 点击右上角「写文章」即可发布新内容。
✍️ 写文章页 (/write)
MINIBLOG - 写文章──────────────────────标题: [_________________________]内容:[_____________________________][_____________________________][ 【发布】按钮 ]
📄 文章详情页 (/post/1)
MINIBLOG──────────────────────【← 返回首页】标题:欢迎来到 MiniBlog时间:2026-03-01 15:40这是第一篇文章...支持换行和段落。
8. 第30天开发计划(明天任务)
✅ 目标:实现可运行的 MVP 版本(首页 + 写文章 + 详情页)
具体步骤:
- 编写
app.py:实现三个路由(/, /write, /post/<int:id>) - 实现
index.html 和 write.html - 测试:发布一篇文章 → 首页显示 → 点击查看详情
💡 提示:
- 用
datetime.now().strftime("%Y-%m-%d %H:%M") 生成时间
🛠️ 关键代码片段预览(app.py 核心逻辑)
# app.py (节选)import jsonimport osfrom datetime import datetimefrom flask import Flask, render_template, request, redirect, url_forapp = Flask(__name__)DATA_FILE = "data/posts.json"def load_posts(): if not os.path.exists(DATA_FILE): return [] with open(DATA_FILE, "r", encoding="utf-8") as f: return json.load(f)def save_posts(posts): os.makedirs("data", exist_ok=True) with open(DATA_FILE, "w", encoding="utf-8") as f: json.dump(posts, f, ensure_ascii=False, indent=2)@app.route("/")def index(): posts = load_posts() posts.reverse() # 最新在前 return render_template("index.html", posts=posts)@app.route("/write", methods=["GET", "POST"])def write(): if request.method == "POST": title = request.form["title"] content = request.form["content"] posts = load_posts() new_id = max([p["id"] for p in posts], default=0) + 1 posts.append({ "id": new_id, "title": title, "content": content, "created_at": datetime.now().strftime("%Y-%m-%d %H:%M") }) save_posts(posts) return redirect(url_for("index")) return render_template("write.html")@app.route("/post/<int:post_id>")def post(post_id): posts = load_posts() post = next((p for p in posts if p["id"] == post_id), None) if not post: return "文章未找到", 404 return render_template("post.html", post=post)
🎉 恭喜!你的项目蓝图已完成!现在你拥有了:
你的 MiniBlog 即将诞生!🚀