首页 > 解决方案 > AttributeError:对象没有属性'user_loader'

问题描述

我在使用 Flask 框架时使用身份验证对网站进行编程。我已经尝试了我在互联网上找到的所有解决方案,但对我没有任何帮助。

我的第一个想法是,项目结构已损坏。例如,缺少来自其他文件的导入。但这不是我认为的问题。

我的 models.py 文件:

from flask_login import UserMixin, LoginManager
from flaskapp import db, login_manager




@login_manager.user_loader
def get_user(user):
    try:
        return get_id(user)
    except:
        return None


class User(db.Model,UserMixin):
    id          =db.Column(db.Integer, primary_key=True)
    username    =db.Column(db.String(20),unique=True, nullable=False)
    email       =db.Column(db.String(120), unique=True, nullable=False)
    password    =db.Column(db.String(60), nullable=False)
    powerlevel  =db.Column(db.Integer, nullable=False)

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return int(self.id)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.powerlevel}')"

我的初始化.py 文件:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager


app = Flask(__name__)
app.config['SECRET_KEY'] = 'xxx'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)


login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager = login_message_category = 'info'




from flaskapp import routes

使用以下命令运行 WebApp 时:

导出 FLASK_APP=run.py DEBUG=TRUE 烧瓶运行

出现以下错误消息:

Traceback (most recent call last):
  File "/home/osboxes/.local/bin/flask", line 11, in <module>
    sys.exit(main())
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 966, in main
    cli.main(prog_name="python -m flask" if as_module else None)
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 586, in main
    return super(FlaskGroup, self).main(*args, **kwargs)
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/home/osboxes/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 848, in run_command
    app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 305, in __init__
    self._load_unlocked()
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 330, in _load_unlocked
    self._app = rv = self.loader()
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 388, in load_app
    app = locate_app(self, import_name, name)
  File "/home/osboxes/.local/lib/python3.6/site-packages/flask/cli.py", line 240, in locate_app
    __import__(module_name)
  File "/home/osboxes/Desktop/HMI/run.py", line 1, in <module>
    from flaskapp import app
  File "/home/osboxes/Desktop/HMI/flaskapp/__init__.py", line 21, in <module>
    from flaskapp import routes
  File "/home/osboxes/Desktop/HMI/flaskapp/routes.py", line 6, in <module>
    from flaskapp.models import User
  File "/home/osboxes/Desktop/HMI/flaskapp/models.py", line 7, in <module>
    @login_manager.user_loader
AttributeError: 'str' object has no attribute 'user_loader'

现在我不知道还有什么问题。如果我忘记提供一些代码来解决错误,请告诉我。感谢您的帮助!

标签: pythonpython-3.xflaskflask-sqlalchemyflask-login

解决方案


首先,您User.get_id应该返回unicode的不是int. 文档提到了这一点,并附有一个示例:

此方法必须返回唯一标识此用户的 unicode,并可用于从 user_loader 回调中加载用户。请注意,这必须是 unicode - 如果 ID 本身是 int 或其他类型,则需要将其转换为 unicode。(您的用户类

所以需要改成:

def get_id(self):
    return unicode(self.id)

Next up, your user_loader. From the docs:

This sets the callback for reloading a user from the session. The function you set should take a user ID (a unicode) and return a user object, or None if the user does not exist.

Which would mean adjusting your user_loader to be something like:

@login_manager.user_loader
def get_user(user_id):
    try:
        return User.query.get(int(user_id))
    except:
        return None

Also, you have an error here, which is likely the direct cause of the error:

login_manager = login_message_category = 'info'

So your taking your login_manager and replacing it with a string with the contents 'info'. So later when your app tries to access login_manager.user_loader it's failing, because a string 'info' doesn't have a user_loader method.

Changing it to the below should fix the error. Though the other issues addressed above also need to be implemented.

login_manager.login_message_category = 'info'

推荐阅读