问题:
**学习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调用栈: