Flask引入Blueprint后报错AttributeError: 'Flask' object has no attribute 'login_manager'
错误原因排查
- 你新增的Blueprint路由使用了
@login_required装饰器,该装饰器是Flask-Login扩展提供的能力,使用前提是已经在Flask app实例上初始化并绑定了LoginManager对象 - 你原有项目的登录逻辑是通过全局变量
current_user手动实现的,没有集成Flask-Login扩展,app实例自然不存在login_manager属性,调用@login_required就会触发属性缺失报错 - 额外注意:当前你同时保留了原有的
@app.route("/index")和新增的蓝图下@bp.route("/index"),如果蓝图没有配置独立url前缀,后续还会出现路由冲突问题
解决方案
方案1:沿用现有手写登录逻辑(改造成本最低)
直接删除Blueprint路由下的@login_required装饰器,复用你原有手动实现的登录校验逻辑即可:
bp = flask.Blueprint("bp", __name__, template_folder="./build") @bp.route('/index') def index(): # 复用原有登录校验逻辑 global current_user if not current_user: return flask.redirect(flask.url_for("login")) # TODO: insert the data fetched by your app main page here as a JSON DATA = {"your": "data here"} data = json.dumps(DATA) return flask.render_template( "index.html", data=data, ) app.register_blueprint(bp)
方案2:完整集成Flask-Login使用@login_required能力
如果希望使用Flask-Login的标准化登录管理能力,按以下步骤配置即可:
安装依赖:
pip install flask-login初始化LoginManager并绑定到app实例,在创建app的代码后添加以下内容:
from flask_login import LoginManager, UserMixin, login_user, current_user login_manager = LoginManager() login_manager.init_app(app) # 配置未登录时自动跳转的登录视图 login_manager.login_view = 'login' # 实现用户加载回调,是Flask-Login要求的必填配置 @login_manager.user_loader def load_user(user_id): cursor.execute("SELECT user_name FROM public.users WHERE user_name = %s", [user_id]) res = cursor.fetchone() if res: user = UserMixin() user.id = res[0] return user return None
- 修改原有login接口,替换全局变量登录逻辑:
@app.route("/login", methods=["GET", "POST"]) def login(): if current_user.is_authenticated: return flask.redirect(flask.url_for("profile")) if flask.request.method == "GET": return flask.render_template("login.html") if flask.request.method == "POST": username = flask.request.form["username"] cursor.execute( "SELECT user_name FROM public.users WHERE user_name = %s", [username] ) results = cursor.fetchall() if len(results) != 0: user = UserMixin() user.id = username login_user(user) return flask.redirect(flask.url_for("profile")) else: return flask.render_template("login.html", error=True)
配置完成后,你原有代码里的全局current_user可以统一替换为Flask-Login提供的current_user,@login_required装饰器也可以正常使用。
内容的提问来源于stack exchange,提问作者Matt Nguyen
相关产品推荐
相关产品推荐

