3、Flask项目初始化与蓝图设计
说实话,每次带新团队做项目,我最先干的事不是写代码,而是先把项目骨架搭好。为什么?因为骨架歪了,后面填肉的时候会非常痛苦。今天我们就来聊聊Flask项目的初始化,以及蓝图这个好东西。
Flask框架核心概念
Flask是个轻量级框架,轻到什么程度?一个文件就能跑起来。但真正做项目,没人会这么干。我见过太多新手把几百行代码塞进一个app.py里,最后自己都找不到路由在哪。
Flask的核心就三个东西:
- 路由:说白了就是URL到函数的映射。你访问
/login,它就知道该调用哪个函数来处理。 - 请求与响应:前端发来的数据怎么拿?返回的数据怎么给?Flask用request和response帮你搞定。
- 上下文:这个稍微抽象点。你可以理解为「当前请求的全局变量」。比如当前登录的用户是谁,存在
g对象里,整个请求周期都能访问。
项目目录结构规划
一个好的目录结构,能让团队协作效率翻倍。我踩过不少坑,最后总结出这套结构,用了好几年,挺顺手的。
online_invest/
├── app/
│ ├── __init__.py # 应用工厂
│ ├── models/ # 数据模型
│ ├── views/ # 视图函数(蓝图)
│ ├── services/ # 业务逻辑层
│ ├── utils/ # 工具函数
│ └── templates/ # HTML模板
├── config/
│ ├── __init__.py
│ ├── default.py # 默认配置
│ └── development.py # 开发环境配置
├── migrations/ # 数据库迁移文件
├── tests/ # 测试用例
├── requirements.txt # 依赖清单
└── run.py # 启动入口
为什么这么分?我解释一下:
- models 只放数据库表结构,不放业务逻辑。我曾经把计算收益的代码写在模型里,后来改需求时差点崩溃。
- services 是业务逻辑层。比如「计算投资收益」这种复杂逻辑,放这里。视图函数只管调用,不管实现。
- views 就是蓝图所在的地方。每个模块一个文件,互不干扰。
蓝图(Blueprint)模块化设计
蓝图是什么?你可以把它理解成「小Flask应用」。每个蓝图有自己的路由、模板、静态文件,最后注册到主应用上。
为什么要用蓝图?举个例子:我们的投资系统有用户模块、产品模块、交易模块。如果所有路由都写在app.py里,光路由就有几十个,维护起来想死的心都有。
来看看怎么用:
# app/views/user.py
from flask import Blueprint
user_bp = Blueprint('user', __name__, url_prefix='/user')
@user_bp.route('/login')
def login():
return "登录页面"
@user_bp.route('/register')
def register():
return "注册页面"
# app/__init__.py
from flask import Flask
from app.views.user import user_bp
def create_app():
app = Flask(__name__)
app.register_blueprint(user_bp)
return app
看到没?每个蓝图只管自己的事。用户模块的代码全在user.py里,产品模块在product.py里。找问题的时候,直接定位到对应文件就行。
url_prefix参数很关键。比如用户模块所有路由都加/user前缀,这样/user/login和/product/list就不会冲突。
配置文件的分离
配置分离这件事,我是吃过亏的。以前有个项目,开发环境和生产环境的数据库地址不一样,结果有次上线忘了改配置,整个系统连的是测试库...用户数据全乱了。
从那以后,我强制团队用这种配置方式:
# config/default.py
class DefaultConfig:
SECRET_KEY = 'dev-secret-key'
SQLALCHEMY_TRACK_MODIFICATIONS = False
# config/development.py
from .default import DefaultConfig
class DevelopmentConfig(DefaultConfig):
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'mysql://dev_user:dev_pass@localhost/invest_dev'
# config/production.py
from .default import DefaultConfig
class ProductionConfig(DefaultConfig):
DEBUG = False
SQLALCHEMY_DATABASE_URI = 'mysql://prod_user:prod_pass@prod_host/invest_prod'
然后在create_app里根据环境变量加载:
def create_app(config_name=None):
app = Flask(__name__)
if config_name is None:
config_name = os.getenv('FLASK_CONFIG', 'development')
config_map = {
'development': 'config.development.DevelopmentConfig',
'production': 'config.production.ProductionConfig'
}
app.config.from_object(config_map[config_name])
return app
这样,不同环境用不同配置,互不干扰。而且配置文件和代码分离,敏感信息也不会泄露。
SECRET_KEY写死在配置文件里,结果代码被同事不小心提交到了公开仓库。现在我用环境变量来存这些敏感信息,配置文件里只写os.getenv('SECRET_KEY')。
知识体系总览
下面这张图,是我做项目时脑子里始终绷着的一根弦。它帮你理清Flask项目初始化的核心脉络:
这张图把今天讲的内容串起来了。你想想看,核心概念是地基,目录结构是框架,蓝图是房间,配置分离是水电线路。四者缺一不可。
好了,这一章的内容就到这里。记住,项目初始化阶段多花点心思,后面能省下大把时间。下一章我们开始动手写代码,把今天设计的结构真正落地。
公众号:蓝海资料掘金营,微信deep3321