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"。
我不明白以下内容:
- 何时何地 "user_loader" 尝试与 user_id
核对
- user_id指的是什么或它的值
- 为什么 user_id 没有从我在登录 app.route.
时创建的用户 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方法时调试我的应用程序时的理解是(回答我的问题):
user_loader
在检查时以及每当我被重定向或页面刷新时执行检查。
user_id
从在登录路由中创建的用户 class 对象获取其值,该对象从登录表单中的用户输入获取。
user_id
没有获得值,因为我在登录 app.route 检查凭据后忘记用 ID 更新用户 class 对象。这意味着我可能能够在不创建@class方法的情况下解决问题(尽管不确定)。
如果我对这3点的理解不正确,请指正。
我目前正在为一门课程做项目,我不允许在我的 Flask 应用程序中使用 ORM,所以我创建了自己的 class,方法是使用 [=49= 查询 sql ]() 命令。
我的问题是,当“@login_manager.user_loader”试图获取 user_id 时,它失败了,因为 id 是 "None"。 我不明白以下内容:
- 何时何地 "user_loader" 尝试与 user_id 核对
- user_id指的是什么或它的值
- 为什么 user_id 没有从我在登录 app.route. 时创建的用户 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:
@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方法时调试我的应用程序时的理解是(回答我的问题):
user_loader
在检查时以及每当我被重定向或页面刷新时执行检查。user_id
从在登录路由中创建的用户 class 对象获取其值,该对象从登录表单中的用户输入获取。user_id
没有获得值,因为我在登录 app.route 检查凭据后忘记用 ID 更新用户 class 对象。这意味着我可能能够在不创建@class方法的情况下解决问题(尽管不确定)。
如果我对这3点的理解不正确,请指正。