如何解决Flask项目中循环导入导致无法导入蓝图bp的报错问题
Flask循环导入报错修复方案
问题根因
当前代码的导入链路形成了循环:
- 运行app.py时,会先执行
from users.home import bp加载蓝图 - 加载
users/home.py时,该文件开头需要从app.py导入contactform和db - 此时app.py还未执行到
db初始化和contactform模型定义的步骤,模块处于未完全初始化状态,最终触发循环导入报错。
解决方案
方案1:调整导入顺序(快速修复)
仅调整app.py的代码执行顺序,将蓝图导入和注册逻辑移动到db、模型定义完成之后即可:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from datetime import datetime # 第一步:初始化app、配置、db实例 app = Flask(__name__) app.config.from_object(__name__) app.config.from_pyfile('myconfig.cfg') app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///QAEngine.db" app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) # 第二步:定义模型 class contactform(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(200), nullable=False) email = db.Column(db.String(200), nullable=False) subject = db.Column(db.String(200), nullable=False) message = db.Column(db.String(500), nullable=False) date_posted = db.Column(db.DateTime, default=datetime.utcnow) def __repr__(self) -> str: return f"{self.name} = {self.email}" # 第三步:db和模型都初始化完成后,再导入注册蓝图 from users.home import bp app.register_blueprint(bp, url_prefix="/user") @app.route("/") def test(): return "<h1>This is test message</h1>" if __name__ == "__main__": app.run()
方案2:拆分公共依赖(长期规范方案)
适合项目后续扩展的写法,把公共依赖拆分到独立文件,避免所有模块都依赖app.py:
- 新建
extensions.py,单独初始化SQLAlchemy实例:
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
- 新建
models.py,存放所有数据库模型:
from datetime import datetime from extensions import db class contactform(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(200), nullable=False) email = db.Column(db.String(200), nullable=False) subject = db.Column(db.String(200), nullable=False) message = db.Column(db.String(500), nullable=False) date_posted = db.Column(db.DateTime, default=datetime.utcnow) def __repr__(self) -> str: return f"{self.name} = {self.email}"
- 修改
users/home.py的导入来源:
from flask import Blueprint, render_template, request from models import contactform from extensions import db bp = Blueprint("bp", __name__, static_folder="static", template_folder="templates") @bp.route("/") def user(): return render_template("home.html") @bp.route("/contact", methods=['POST', 'GET']) def contact(): if request.method == "POST": name = request.form['name'] email = request.form['email'] subject = request.form['subject'] message = request.form['message'] instance = contactform(name=name, email=email, subject=subject, message=message) db.session.add(instance) db.session.commit() return render_template("contact.html")
- 修改
app.py代码:
from flask import Flask from extensions import db from users.home import bp app = Flask(__name__) app.config.from_object(__name__) app.config.from_pyfile('myconfig.cfg') app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///QAEngine.db" app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 绑定db到app db.init_app(app) # 注册蓝图 app.register_blueprint(bp, url_prefix="/user") @app.route("/") def test(): return "<h1>This is test message</h1>" if __name__ == "__main__": # 首次运行需要创建数据库表时,取消下面两行注释 # with app.app_context(): # db.create_all() app.run()
内容的提问来源于stack exchange,提问作者Maqsood Quraishi
相关产品推荐
相关产品推荐

