You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Flask Blueprints与SQLAlchemy的API架构如何简化?

简化Flask Blueprint架构的方案

核心优化方向

针对你提到的Blueprint架构繁琐、依赖分散的问题,核心优化思路是减少中间文件层级、简化蓝图注册流程、让每个实体的路由逻辑更集中,同时保留SQLAlchemy和Marshmallow的现有合理用法。

具体实现方案

方案1:合并路由模块,取消中间__init__.py

将每个实体的HTML和API路由直接放在同一个文件中,不再需要多层级的路由目录结构,同时在文件内直接创建对应的蓝图。

优化后的项目结构

project/
├── app/
│   ├── __init__.py       # 工厂函数
│   ├── models/
│   │   ├── __init__.py   # 导出所有模型和Schema
│   │   └── user.py       # User模型 + UserSchema
│   └── routes/
│       ├── __init__.py   # 可选,仅用于批量导出蓝图
│       └── user.py       # 同时包含用户的HTML和API路由
└── app.py

路由文件示例(app/routes/user.py)

from flask import Blueprint, render_template, jsonify
from app.models import User, UserSchema

# 创建两个蓝图,分别对应HTML界面和API
user_html = Blueprint("user_html", __name__, url_prefix="/users")
user_api = Blueprint("user_api", __name__, url_prefix="/api/users")

# HTML CRUD路由
@user_html.route("/")
def user_list():
    users = User.query.all()
    return render_template("users/list.html", users=users)

@user_html.route("/<int:user_id>")
def user_detail(user_id):
    user = User.query.get_or_404(user_id)
    return render_template("users/detail.html", user=user)

# API CRUD路由
@user_api.route("/")
def api_user_list():
    users = User.query.all()
    schema = UserSchema(many=True)
    return jsonify(schema.dump(users))

@user_api.route("/<int:user_id>")
def api_user_detail(user_id):
    user = User.query.get_or_404(user_id)
    schema = UserSchema()
    return jsonify(schema.dump(user))

蓝图注册简化(app/__init__.py)

直接从路由文件导入蓝图并注册,无需中间层级的导入:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

db = SQLAlchemy()
ma = Marshmallow()

def create_app():
    app = Flask(__name__)
    app.config.from_object("config.Config")

    # 初始化扩展
    db.init_app(app)
    ma.init_app(app)

    # 注册蓝图 - 直接导入
    from app.routes.user import user_html, user_api
    app.register_blueprint(user_html)
    app.register_blueprint(user_api)

    # 其他实体的蓝图同理添加
    # from app.routes.product import product_html, product_api
    # app.register_blueprint(product_html)
    # app.register_blueprint(product_api)

    return app

方案2:自动扫描注册蓝图(进一步减少修改)

如果实体较多,可以用动态导入实现蓝图自动注册,新增路由文件后无需修改create_app函数。

修改app/__init__.py的工厂函数:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import importlib
import os

db = SQLAlchemy()
ma = Marshmallow()

def create_app():
    app = Flask(__name__)
    app.config.from_object("config.Config")

    db.init_app(app)
    ma.init_app(app)

    # 自动扫描routes目录下的所有路由文件
    routes_dir = os.path.join(os.path.dirname(__file__), "routes")
    for filename in os.listdir(routes_dir):
        if filename.endswith(".py") and filename != "__init__.py":
            # 导入路由模块
            module_name = f"app.routes.{filename[:-3]}"
            module = importlib.import_module(module_name)
            # 遍历模块中的属性,注册所有Blueprint实例
            for attr_name in dir(module):
                attr = getattr(module, attr_name)
                if isinstance(attr, Blueprint):
                    app.register_blueprint(attr)

    return app

这样新增实体时,只需要在routes目录下创建对应的路由文件(如product.py),定义好product_html和product_api蓝图,启动时会自动注册,完全不需要修改工厂函数。

优化后的优势

  • 减少修改点:新增实体路由仅需创建一个路由文件,无需修改多个__init__.py
  • 结构清晰:每个实体的HTML和API路由集中在同一个文件,与模型/Schema的关联更直观
  • 降低依赖分散:路由逻辑与对应实体强绑定,避免跨文件的隐式依赖
  • 扩展性好:自动扫描模式下,新增实体的成本极低,适合后续功能迭代

内容的提问来源于stack exchange,提问作者Tom Harrison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:24:56