第 1 章 · Flask 入门与应用工厂
本章目标:理解 Flask 微框架定位与应用工厂(Application Factory)模式;在独立 venv 中安装 Flask 并创建虚构练习项目 api-demo;实现最小 Hello 路由与 create_app() 工厂函数;掌握 flask run 开发服务器与调试模式;能用对照表说明 Flask 与 Django(shop-demo)在体量、路由、ORM 上的差异。
学时建议:3~4 小时(含 1 小时跟练)
前置:完成 python-dev ch10(python -m venv、pip 安装、激活虚拟环境);学过 django-web 更佳但非必须。
1.1 场景说明:为什么选 Flask 做 api-demo?
你在 django-web 中用 shop-demo 搭建了完整电商后台——MTV、Admin、ORM 一应俱全。现在团队要做一个轻量 REST 服务 + 少量管理页,对外域名规划为虚构的 https://api.example.com(教学占位,非真实生产地址)。
| 维度 | shop-demo(Django) | api-demo(Flask) |
|---|---|---|
| 定位 | 全功能后台、Admin 优先 | API 优先、页面极简 |
| 项目体量 | 多 App、settings 分包 | 单包 + 蓝图(ch02) |
| 默认 ORM | Django ORM | SQLAlchemy(ch05) |
| 模板 | DjangoTemplates | Jinja2(ch03) |
| 适合场景 | 内容站、运营后台 | 微服务、内部 API、原型 |
说明:本章所有路径、域名、密钥均为教学虚构,不涉及任何真实公司仓库、内部配置或生产域名。
学习路径(flask-web)
ch01 应用工厂 → ch02 蓝图 → ch03 模板 → ch04 表单
↑ 你在这里
1.2 Flask 与 Django 对比表
| 对比项 | Flask | Django |
|---|---|---|
| 哲学 | 微框架,按需组装扩展 | 全栈框架,batteries included |
| 路由 | 装饰器 @app.route / Blueprint | urls.py + path() |
| 配置 | app.config 字典 / 环境变量 | settings.py 模块 |
| 数据库 | 需 Flask-SQLAlchemy 等扩展 | 内置 ORM + migrations |
| 表单 | Flask-WTF(ch04) | forms.Form / ModelForm |
| 认证 | Flask-Login(ch06) | django.contrib.auth |
| 开发服务器 | flask run | manage.py runserver |
| 项目结构 | 应用工厂 + 蓝图,无强制约定 | 项目 + App 强制分层 |
| 学习曲线 | 先小后大,扩展自选 | 概念多但路径清晰 |
| 典型部署 | Gunicorn + Nginx(ch11) | 同左 |
何时选 Flask:API 网关、Webhook、小型服务、与现有非 Python 系统对接;需要最小依赖与灵活结构。
何时选 Django:复杂后台、权限体系、Admin、内容管理、多 App 大型站点。
1.3 环境准备(venv + pip)
与 python-dev ch10 相同,在独立目录练习,勿与 shop-demo 共用 venv。
cd ~/python-learn
mkdir api-demo && cd api-demo
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
# source .venv/bin/activate
pip install "flask>=3.0,<4"
flask --version
requirements.txt(建议尽早维护):
flask>=3.0,<4
| 命令 | 作用 |
|---|---|
python -m venv .venv | 创建隔离环境 |
pip install flask | 安装核心包 |
pip freeze > requirements.txt | 锁定版本供协作 |
1.4 最小 Hello(单文件版)
先理解核心概念,再升级为工厂模式。
hello.py(临时练习,可删除):
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hello, api-demo!"
@app.route("/health")
def health():
return {"status": "ok", "service": "api-demo"}
if __name__ == "__main__":
app.run(debug=True, port=5000)
运行:
python hello.py
浏览器访问 http://127.0.0.1:5000/ 与 http://127.0.0.1:5000/health。
| URL | 响应类型 | 说明 |
|---|---|---|
/ | 纯文本 | 最小路由 |
/health | JSON 字典 | Flask 自动序列化 dict |
1.5 应用工厂 create_app()
单文件 app = Flask(__name__) 不利于测试与多配置。应用工厂通过函数创建 Flask 实例,是 Flask 官方推荐结构。
推荐目录(api-demo):
api-demo/
├── .venv/
├── requirements.txt
├── .env.example # FLASK_APP、SECRET_KEY 示例(无真实密钥)
├── wsgi.py # 生产入口(ch11)
├── api_demo/ # 应用包(Python 包名用下划线)
│ ├── __init__.py # create_app 工厂
│ ├── config.py # 配置类
│ ├── extensions.py # 扩展占位(ch05 起使用)
│ └── routes/
│ └── main.py # 根路由
└── tests/ # ch11 测试
api_demo/config.py:
import os
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-only-change-in-prod")
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
config_map = {
"development": DevelopmentConfig,
"production": ProductionConfig,
"default": DevelopmentConfig,
}
api_demo/extensions.py(本章仅占位):
# ch05 将在此注册 db、migrate;ch06 注册 login_manager
api_demo/routes/main.py:
from flask import Blueprint
bp = Blueprint("main", __name__)
@bp.route("/")
def index():