3. Flask项目初始化
好,咱们正式开始动手了。前面两章聊了需求分析和设计思路,现在轮到真正敲代码的时候。这一章的目标很简单——把 Flask 项目跑起来,然后写一个 Hello World 接口。别小看这一步,项目结构搭得好,后面几十章你会感谢自己。
3.1 虚拟环境:为什么必须搞?
先问个问题:你电脑上可能同时有好几个 Python 项目,有的用 Flask 2.x,有的用 Flask 1.x,有的依赖包版本还互相打架。怎么办?
虚拟环境就是干这个的。它给每个项目一个独立的 Python 解释器和包空间,互不干扰。我刚开始学的时候嫌麻烦,直接在全局装包,结果有一次把 Django 项目搞崩了,折腾了一下午才恢复。嗯,从那以后我再也不敢偷懒了。
3.1.1 创建虚拟环境
Python 3.3 以上自带 venv 模块,不需要额外安装。打开终端,进到你的项目根目录,执行:
python3 -m venv venv
这条命令会在当前目录下生成一个 venv 文件夹,里面就是独立的 Python 环境。
venv,简单明了。也有人用 .venv,看团队规范。
3.1.2 激活虚拟环境
不同操作系统激活方式不一样,我列个表:
| 操作系统 | Shell | 激活命令 |
|---|---|---|
| Windows | CMD | venv\Scripts\activate.bat |
| Windows | PowerShell | venv\Scripts\Activate.ps1 |
| macOS / Linux | bash / zsh | source venv/bin/activate |
激活后,终端前面会出现 (venv) 字样,说明你已经在虚拟环境里了。这时候装任何包都不会影响全局。
venv/bin/python,否则终端和编辑器用的可能不是同一个环境。我曾经因为这个排查了半小时,结果发现包装到了全局。
3.2 安装 Flask
虚拟环境激活后,装 Flask 就一行命令:
pip install flask
装完之后,可以用 pip list 看看都装了哪些依赖。你会发现 Flask 自己还带了一堆小工具,比如 Werkzeug(WSGI 工具库)、Jinja2(模板引擎)、click(命令行工具)。这些 Flask 帮你管好了,你不用操心。
我建议把依赖写进文件,方便别人(或者未来的你)复现环境:
pip freeze > requirements.txt
以后别人拿到项目,直接 pip install -r requirements.txt 就能装好所有依赖。这个习惯我从第一个项目就开始用,到现在没断过。
3.3 项目目录结构设计
很多人一上来就写 app.py,把所有代码塞进去。小项目还行,一旦功能多了,那个文件能写到上千行,找东西全靠 Ctrl+F。我见过最夸张的一个项目,一个文件 3000 多行,后来没人敢改。
所以,一开始就把目录结构搭好。下面是我个人比较推荐的结构,适合配方管理系统这种中小型项目:
recipe_manager/
├── venv/ # 虚拟环境(不提交到 Git)
├── app/ # 应用主目录
│ ├── __init__.py # 初始化 Flask 应用
│ ├── routes/ # 路由模块
│ │ ├── __init__.py
│ │ └── recipe.py # 配方相关接口
│ ├── models/ # 数据模型
│ │ ├── __init__.py
│ │ └── recipe.py
│ ├── services/ # 业务逻辑层
│ │ ├── __init__.py
│ │ └── recipe_service.py
│ ├── templates/ # HTML 模板(如果有前端页面)
│ └── static/ # 静态文件(CSS/JS/图片)
├── config.py # 配置文件
├── requirements.txt # 依赖清单
├── run.py # 启动入口
└── README.md # 项目说明
这个结构的好处是:路由、模型、业务逻辑各司其职,每个文件只干一件事。后面加功能的时候,你只需要在对应目录下新建文件,不会动到已有的代码。
3.4 第一个 Hello World 接口
好,终于到写代码的环节了。咱们先写一个最简单的接口,验证整个链路通不通。
3.4.1 创建应用入口
在项目根目录下创建 run.py:
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
这里用 create_app 函数来创建应用实例,这是 Flask 的工厂模式,后面扩展功能会很方便。
3.4.2 初始化 Flask 应用
在 app/__init__.py 里写:
from flask import Flask
def create_app():
app = Flask(__name__)
# 注册蓝图(后面会讲)
from .routes.recipe import recipe_bp
app.register_blueprint(recipe_bp)
return app
这里用到了蓝图(Blueprint),Flask 里组织路由的官方方式。简单说,就是把一组相关的路由打包成一个模块,然后注册到应用上。
3.4.3 写第一个路由
在 app/routes/recipe.py 里:
from flask import Blueprint, jsonify
recipe_bp = Blueprint('recipe', __name__)
@recipe_bp.route('/api/hello', methods=['GET'])
def hello():
return jsonify({
'message': 'Hello, Recipe Manager!',
'version': '1.0.0'
})
这个接口返回一个 JSON 对象,包含欢迎信息和版本号。为什么用 jsonify 而不是直接返回字典?因为 jsonify 会自动设置 Content-Type: application/json,而且能处理一些特殊数据类型。
3.4.4 启动并测试
在终端执行:
python run.py
看到类似这样的输出,说明启动成功:
* Serving Flask app 'app'
* Debug mode: on
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://192.168.1.100:5000
打开浏览器,访问 http://127.0.0.1:5000/api/hello,你应该能看到:
{
"message": "Hello, Recipe Manager!",
"version": "1.0.0"
}
debug=True 后,代码修改会自动重启服务器,不用手动停掉再启动。但生产环境千万别开,会有安全风险。
3.5 本章知识结构图
下面这张图把本章的核心流程串起来了,从创建虚拟环境到第一个接口返回,每一步都清晰可见:
3.6 常见问题与避坑
写第一个接口的时候,有几个坑我几乎每次带新人都会遇到:
- 端口被占用: 如果启动时提示
Address already in use,说明 5000 端口已经被别的程序占了。换个端口,或者用lsof -i :5000找到占用进程杀掉。 - 蓝图没注册: 写了路由但访问返回 404,八成是忘了在工厂函数里
register_blueprint。我 debug 过最久的一次,就是因为这个。 - 虚拟环境没激活: 终端前面没有
(venv)提示,直接pip install flask装到了全局。后果就是项目里 import 不到 flask。
venv/ 文件夹提交到 Git。在项目根目录创建 .gitignore 文件,写上 venv/ 和 __pycache__/。否则别人 clone 你的项目,光下载虚拟环境就得等半天。
好了,到这一步,你的 Flask 项目已经跑起来了,第一个接口也返回了数据。虽然只是 Hello World,但整个链路——从环境搭建、项目结构、到路由注册、JSON 响应——全都走通了。后面每一章都会在这个基础上加功能,所以这一章的基础打得越扎实,后面就越顺手。