数据库里已经躺着「古典文学网」的六篇作品(课程一),但用户打开浏览器时,看到的不能是一堆 SQL 结果。中间缺的这个人,就是后端:它接收前端的请求、查库、算出结果,再用 JSON 交回去。本章让你把第一行 Flask 代码跑起来,并在浏览器里看到它的响应——从这一章起,「古典文学网」正式开始长成。
前端只管「点单」(发请求、收 JSON),后端只管「做菜」(查库、出结果);两边靠事先约定好的接口契约对接。
GET /api/article/list?page=1&page_size=2 HTTP/1.1
Host: 127.0.0.1:5000
整个系统分三层:表现层(前端)在最上,数据层(数据库)在最下,后端就是中间那层「接口层」,负责把上层的请求翻译成对下层的操作。
cd ~/pyweb
tree -L 2
每个项目有自己的 venv(一口独立的锅),装各自的依赖版本。它们都基于系统 Python 创建,但彼此隔离,不会出现「装了新包把旧项目搞坏」的情况。
# 1. 在项目根目录里创建虚拟环境,会生成一个 venv/ 文件夹
python3 -m venv venv
# 2. 激活它(激活成功后命令行前面会出现 (venv))
source venv/bin/activate # macOS / Linux
venv\Scripts\Activate.ps1 # Windows PowerShell
# 3. 现在再装包,就装进这个项目的 venv 里了
pip install flask
# 4. 不用了,退出虚拟环境
deactivate
四行代码跑起来的最小闭环:浏览器发请求 → WSGI 服务器转交 → 路由匹配到函数 → 返回值变成响应回到浏览器。
from flask import Flask, jsonify
app = Flask(__name__)
app.json.ensure_ascii = False # 让 jsonify 直接输出中文,而不是 \uXXXX 转义
@app.route("/")
def index():
return jsonify({"msg": "古典文学网 API 已启动", "version": "1.0"})
if __name__ == "__main__":
app.run(debug=True)
目录规范的本质是「分层」:主程序、依赖清单、虚拟环境、静态资源各归各位。venv 不入库,换机器时 pip install -r requirements.txt 就能还原环境。
hiflask/
├── app.py # 入口:创建 app、注册蓝图、启动
├── config.py # 配置:数据库地址、密钥、上传目录
├── extensions.py # 扩展实例:db / jwt / cors(先留空,第 6 章填)
├── models/ # 数据模型,一张表一个文件
│ ├── __init__.py
│ ├── user.py # user 表
│ ├── article.py # article 表
│ └── comment.py # comment 表
├── views/ # 接口(蓝图),一个模块一个文件
│ ├── __init__.py
│ ├── user.py # /api/user/...
│ └── article.py # /api/article/...
├── static/
│ └── upload/ # 用户上传的头像、封面(第 9 章用)
├── requirements.txt # 依赖清单,别人照这个装
├── .gitignore # 忽略 venv/、__pycache__/、.env
└── venv/ # 虚拟环境(不进版本库)
Flask==3.0.3
Flask-SQLAlchemy==3.1.1
Flask-Cors==4.0.1
PyJWT==2.8.0
PyMySQL==1.1.1
# 最简写法,看返回内容
curl http://127.0.0.1:5000/
# 带 -s 安静模式(不显示进度条),管道给 python 格式化,中文更清楚
curl -s http://127.0.0.1:5000/ | python -m json.tool --indent 2
# 只看 HTTP 状态码
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:5000/
后端框架名字听着都像:Flask、Django、FastAPI,再往外还有 Node 的 Express、Java 的 Spring Boot。它们不是谁比谁「高级」,而是解决不同规模、不同场景的问题。下面按几个常用维度把主流框架摆在一起,重点不是记结论,而是看懂「每种选择背后在权衡什么」。
| 维度 | Flask(本课) | Django | FastAPI | Express(Node) | Spring Boot(Java) |
|---|---|---|---|---|---|
| 定位 / 哲学 | 微框架:只给核心,其余你来拼 | 全家桶:电池已备齐 | 异步优先的 API 框架 | 极简、自由组合的 Node 框架 | 企业级一站式方案 |
| 学习曲线 | 平缓:先跑起来,再学扩展 | 较陡:概念多(MTV / ORM / 表单) | 中等:需懂类型注解与异步 | 平缓,但 JS 生态杂 | 陡:强类型、配置多 |
| 内置功能 | 路由、请求解析;ORM / Admin 靠扩展 | ORM、Admin、表单、鉴权开箱即用 | 依赖注入、数据校验、自动文档 | 几乎都要自己装中间件 | 安全、事务、消息队列等齐全 |
| 异步支持 | 3.x 起原生支持 async 视图 | 新版本支持,但非默认 | 天生异步,是性能强项 | 事件循环,天然异步 | 支持,靠协程 / 响应式 |
| 性能 / 吞吐 | 中(同步默认,教学够用) | 中 | 高(异步 + Pydantic) | 中高 | 高且稳,企业首选 |
| 生态 / 社区 | 庞大,扩展多,中文资料多 | 极大,教程与包极丰富 | 较新但增长快,AI 圈爱用 | 最大(npm),但质量参差 | 成熟庞大,企业文档全 |
| 典型适用场景 | 教学、中小项目、微服务、API 网关 | 内容站、后台、快速建站 | 高并发 API、ML 服务 | JS 全栈、实时应用 | 大型分布式系统 |
横向看每一列:没有「最好」的框架,只有「最贴合当前问题」的框架。
# 第 1 题(命令行)
# mkdir hiflask && cd hiflask
# python3 -m venv venv
# source venv/bin/activate
# pip install flask
# pip freeze > requirements.txt
# 第 2、3 题:app.py
from flask import Flask, jsonify
app = Flask(__name__)
app.json.ensure_ascii = False
# 第 2 题:健康检查
@app.route("/health")
def health():
return jsonify({"status": "ok"})
# 第 3 题:红影赏析最小骨架(himovie/ 目录同 hiflask)
# himovie/
# ├── app.py ├── config.py ├── extensions.py
# ├── models/ ├── views/ ├── requirements.txt └── venv/
@app.route("/api/movie/list")
def movie_list():
# 还没连数据库,先返回两条假数据,只为验证「请求 → 响应」这条链路
movies = [
{"id": 1, "title": "流浪地球", "genre": "科幻", "rating": 8.4},
{"id": 2, "title": "星际穿越", "genre": "科幻", "rating": 9.3},
]
return jsonify({
"code": 200,
"msg": "success",
"data": {"list": movies, "total": 2, "page": 1, "page_size": 10},
})
if __name__ == "__main__":
app.run(debug=True)
第 2 题的答案:return "ok" 返回的是纯文本,Content-Type 是 text/html,前端拿到的是字符串不是对象,还得自己再解析一遍。要返回结构化数据,就用 jsonify()。第 3 题的关键:换的是项目名、表名和字段名,不变的还是那一套「建环境 → 写路由 → 返回 JSON → curl 验证」的流程。
做完点「检查本节」看解析与得分;做错可重做。