Flask中在__init__.py注册Blueprint失败的原因及优化方案
Flask Blueprint 注册后路由消失的原因与优化写法
问题原因:模块加载顺序导致路由未绑定
你遇到的问题本质是模块加载顺序引发的路由装饰器未执行:
- 在
test_bad结构中,app.py导入test_bad.create_app时,会先加载test_bad/__init__.py __init__.py仅导入了routes.py中的dash蓝图对象,但此时views.py并未被加载,因此views.py里的@dash.route装饰器完全没机会执行,dash蓝图实际上是空的- 后续
create_app把这个空蓝图注册到Flask应用,自然不会有任何路由规则被添加
而test_good能正常工作,是因为app.py直接导入test_good.views.create_app,加载views.py时会先导入dash蓝图,接着执行所有路由装饰器,把路由绑定到蓝图上,最后注册到应用时路由已经存在。
更优的项目结构与写法
合理的结构应该保持分层清晰:routes.py定义蓝图,views.py实现路由逻辑,__init__.py负责应用初始化与蓝图注册,同时确保视图模块在蓝图注册前被加载。
推荐目录结构
project/ ├── app.py └── test_opt/ ├── __init__.py ├── routes.py └── views.py
各文件代码实现
app.py
from test_opt import create_app if __name__ == '__main__': app = create_app() for rule in app.url_map.iter_rules(): print(rule) app.run(debug=True, use_reloader=False)
test_opt/init.py
from flask import Flask from .routes import dash # 关键:提前导入视图模块,触发路由装饰器执行 from . import views def create_app(): app = Flask(__name__) app.register_blueprint(dash) return app
test_opt/routes.py
from flask import Blueprint # 定义蓝图对象 dash = Blueprint('dash', __name__)
test_opt/views.py
from .routes import dash @dash.route('/', methods=['GET', 'POST']) def index(): return '<html><body><h1>Hello World!</h1></body></html>' @dash.route('/verify', methods=['GET','POST']) def check_verification(): return '<html><body><h1>And Farewell!</h1></body></html>'
另一种简洁写法(路由文件导入视图)
也可以在routes.py中直接导入视图模块,这样__init__.py无需额外导入视图:
修改test_opt/routes.py
from flask import Blueprint dash = Blueprint('dash', __name__) # 导入视图,自动触发路由装饰器执行 from . import views
此时test_opt/init.py可简化为
from flask import Flask from .routes import dash def create_app(): app = Flask(__name__) app.register_blueprint(dash) return app
核心总结
- 蓝图本身只是容器,必须确保所有绑定该蓝图的视图模块被加载,路由装饰器才会把规则注册到蓝图上
- 保持结构分层:入口文件启动应用,
__init__.py管理应用初始化,routes定义蓝图,views实现业务路由,既清晰又避免加载顺序问题
内容的提问来源于stack exchange,提问作者Tunneller
相关产品推荐
相关产品推荐

