Flask_login user_loader() 函数的问题给我 None

Flask_login problem with user_loader() function giving me None

我目前正在为一门课程做项目,我不允许在我的 Flask 应用程序中使用 ORM,所以我创建了自己的 class,方法是使用 [=49= 查询 sql ]() 命令。

我的问题是,当“@login_manager.user_loader”试图获取 user_id 时,它失败了,因为 id 是 "None"。 我不明白以下内容:

  1. 何时何地 "user_loader" 尝试与 user_id
  2. 核对
  3. user_id指的是什么或它的值
  4. 为什么 user_id 没有从我在登录 app.route.
  5. 时创建的用户 class 获取值 ID

注意:如果我将我正在搜索的内容从 id 更改为用户名,代码可以正常工作,网站也可以正常工作,
但是 current_user.is_authenticated: 不起作用,即使使用不同的用户帐户,我也可以继续登录任意多次。

我的应用当前打包有以下文件树:

这是 models.py 中用户 Class 的代码片段:

@login_manager.user_loader
def load_user(user_id):
    return User.searchwo(id=user_id)

class User(UserMixin):

    def __init__(self, username, password=None, id=None):
        self.username = username
        self.password = password
        self.id = id

    def create(self):
        db.session.execute("INSERT INTO users (username, password) VALUES (:username, :password)", {"username": self.username, "password": self.password})
        db.session.commit()

    def search(self):
        response = db.session.execute("SELECT id,username,password FROM users WHERE username = :username", {"username":self.username}).fetchone()
        if response != None:
            self.id = response[0]
            self.password = response[2]
        return response

    @staticmethod
    def searchwo(id=None, username=None):
        if id != None:
            response = db.session.execute("SELECT id,username,password FROM users WHERE id = :id", {"id":id}).fetchone()
        elif username != None:
            response = db.session.execute("SELECT id,username,password FROM users WHERE username = :username", {"username":username}).fetchone()
        return response

这是routes.py中的登录代码片段:

我在 "user = User(....."

处创建了一个用户对象 class
@app.route("/", methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('main'))
    form = LoginForm()
    if form.validate_on_submit():
        usertemp = User.searchwo(username=form.username.data)
        if usertemp == None:
            user = None
        else:
            user = User(usertemp[1], password=usertemp[2])
        if user and bcrypt.check_password_hash(user.password, form.password.data):
            login_user(user, remember=form.remember.data)
            return redirect(url_for('main'))
        else:
            flash('Invalid credentials! if your not a user please register first.')
    return render_template('index.html', title='Book Reviews', form=form)

所以我想出了如何通过创建@class方法来解决我的问题。 我是 python 的新手,所以我在学习中还没有达到 @class 方法。
但是通过创建 @class 方法,我能够正确地 return user_loader 通常 return 的对象类型,而不是我 return 的元组类型在原始代码中。 这是我在 User class:

末尾创建的@class方法
    @classmethod
    def searchid(cls, id):
        response = db.session.execute("SELECT id,username,password FROM users WHERE id = :id", {"id":id}).fetchone()
        return cls(response[1], response[2], response[0])

    @classmethod
    def searchuser(cls, username):
        response = db.session.execute("SELECT id,username,password FROM users WHERE username = :username", {"username":username}).fetchone()
        return cls(response[1], response[2], response[0])

这是 user_loader 现在的样子:

@login_manager.user_loader
def load_user(user_id):
    return User.searchid(id=user_id)

根据我在创建@class方法时调试我的应用程序时的理解是(回答我的问题):

  1. user_loader 在检查时以及每当我被重定向或页面刷新时执行检查。
  2. user_id 从在登录路由中创建的用户 class 对象获取其值,该对象从登录表单中的用户输入获取。
  3. user_id 没有获得值,因为我在登录 app.route 检查凭据后忘记用 ID 更新用户 class 对象。这意味着我可能能够在不创建@class方法的情况下解决问题(尽管不确定)。

如果我对这3点的理解不正确,请指正。