问题:
**学习flask-login中,许多教程都说需要定义这个函数,但是都没有说清楚这个函数什么时候被调用所以请问
1.load_user函数什么时候被调用了
2.为什么需要填写load_user函数,具体到底是做什么的
@login_manager.user_loader
def load_user(user_id):
"""加载用户的函数"""
return User.query.get(int(user_id))
解答:
要了解load_user的作用,先来看一下flask-login 是怎么工作的:
@admin.rotue('/')
@login_required
def index():
return render_template('index.html')
当我们访问/admin时,flask-login会检查是否登录没有登录时会跳转到登录页,其实现在装饰器内部,源码也很简单,可以去看看。当跳转到登录页时,提交完表单之后要调用login_user函数:
login_user(user,remember=form.remember_me.data)
在login_user函数内部:
user_id = getattr(user, current_app.login_manager.id_attribute)()
session['user_id'] = user_id
session['_fresh'] = fresh
session['_id'] = _create_identifier()
if remember:
session['remember'] = 'set'
_request_ctx_stack.top.user = user
user_logged_in.send(current_app._get_current_object(), user=_get_user())
可以看到,我们手动调用是将user的属性写入session,并绑定到当前的请求上下文。由于HTTP是无状态连接,每次发起新请求时flask 会创建一个请求上下文,在分发路由时flask-login根据cookie判断用户并绑定到当前的请求上下文,由于这种绑定关系的存在,那么每次新的请求发生时都需要获取user 看一下最后绑定的代码:
def reload_user(self, user=None):
ctx = _request_ctx_stack.top
if user is None:
user_id = session.get('user_id')
if user_id is None:
ctx.user = self.anonymous_user()
else:
if self.user_callback is None:
raise Exception(
"No user_loader has been installed for this "
"LoginManager. Add one with the "
"'LoginManager.user_loader' decorator.")
user = self.user_callback(user_id)
if user is None:
ctx.user = self.anonymous_user()
else:
ctx.user = user
else:
ctx.user = user
self.user_callback就是实现的load_user方法,那么其作用就是每次新请求时调用该方法获取user并绑定到当前的请求上下文,绑定的意义在于每次当我们使用current_user的时候,会直接从当前上下文中返回。
最后附上一张一次请求flask调用栈: