3、Flask项目初始化与蓝图设计

说实话,每次带新团队做项目,我最先干的事不是写代码,而是先把项目骨架搭好。为什么?因为骨架歪了,后面填肉的时候会非常痛苦。今天我们就来聊聊Flask项目的初始化,以及蓝图这个好东西。

Flask框架核心概念

Flask是个轻量级框架,轻到什么程度?一个文件就能跑起来。但真正做项目,没人会这么干。我见过太多新手把几百行代码塞进一个app.py里,最后自己都找不到路由在哪。

Flask的核心就三个东西:

  • 路由:说白了就是URL到函数的映射。你访问/login,它就知道该调用哪个函数来处理。
  • 请求与响应:前端发来的数据怎么拿?返回的数据怎么给?Flask用request和response帮你搞定。
  • 上下文:这个稍微抽象点。你可以理解为「当前请求的全局变量」。比如当前登录的用户是谁,存在g对象里,整个请求周期都能访问。
我的小习惯: 刚开始学Flask时,我总把路由和视图函数写在一起。后来项目大了,改一个路由要翻半天文件。现在我习惯把路由单独抽出来,哪怕小项目也这么做。

项目目录结构规划

一个好的目录结构,能让团队协作效率翻倍。我踩过不少坑,最后总结出这套结构,用了好几年,挺顺手的。

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 就是蓝图所在的地方。每个模块一个文件,互不干扰。
注意: 千万别把配置文件写死在代码里。我见过有人把数据库密码直接写在app.py里,结果代码传到GitHub上...嗯,那场面挺尴尬的。

蓝图(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项目初始化的核心脉络:

Flask项目初始化 框架核心概念 路由 · 请求响应 上下文 目录结构规划 models/views/services utils/templates 蓝图模块化设计 用户蓝图/产品蓝图 交易蓝图 配置文件分离 开发/生产配置 环境变量 核心目标:可维护 · 可扩展 · 可测试 模块解耦 · 配置灵活 · 团队协作高效

这张图把今天讲的内容串起来了。你想想看,核心概念是地基,目录结构是框架,蓝图是房间,配置分离是水电线路。四者缺一不可。

好了,这一章的内容就到这里。记住,项目初始化阶段多花点心思,后面能省下大把时间。下一章我们开始动手写代码,把今天设计的结构真正落地。


公众号:蓝海资料掘金营,微信deep3321