DAY 215 Flask中before_request与after_request使用
如果有一天公司业务需求需要给所有视图函数添加功能,可以通过装饰器实现,但视图函数太多,有没有更好的办法呢?
before_request与after_request很简单,实现中功能同Django中中间件process_request与process_response的功能相同
一、前提,装饰器的弊端
我们现在有一个 Flask 程序其中有3个路由和视图函数,如下:
from flask import Flask app = Flask(__name__) # type:Flask @app.route("/login") def login(): return "Login" @app.route("/index") def index(): return "Index" @app.route("/home") def home(): return "Login" app.run("0.0.0.0", 5000)
如果登陆了,就可以访问 index 和 home 页面,如果没登录就跳转到 login 登录
要怎么解决呢, session 对, 用 session 除了 Login 函数之外的所有函数里面全校验 session 是否登录了
太麻烦了,现在咱们只有3个函数,如果成百上千个怎么整啊
装饰器,对没错,装饰器是一个很好的方案,但是啊,我现在还是成败上千个函数,我要在每一个函数定义的时候加上@装饰器,还是很麻烦
二、before_request与after_request
2.1 before_request分析:
from flask import Flask, render_template app = Flask(__name__) @app.route("/home") def home(): return "Hello" @app.before_request def be1(): print("be1") return "出错了" # return None @app.before_request def be2(): print("be2") return None @app.after_request def af1(res): print("af1") return res @app.after_request def af2(res): print("af2") return res if __name__ == '__main__': app.run()
报错信息:
注意:对比
# Django中,如果当请求到达请求1的时候直接不符合条件返回,即return HttpResponse("Md1中断"),程序将把请求直接发给中间件1返回,然后依次返回到请求者,不再执行视图函数
# 在Flask中,如果当请求到达请求1的时候直接不符合条件返回,则会中最后一个@app.after_request中依次返回到请求者,不再执行视图函数,结果如下: 返回Md2中断的页面,后台打印如下:
be1
af2
af1
2.2 after_request分析:
@app.after_request报错则会依次返回结果
from flask import Flask, render_template app = Flask(__name__) @app.route("/home") def home(): return "Hello" @app.before_request def be1(): print("be1") # return "出错了" return None @app.before_request def be2(): print("be2") return None @app.after_request def af1(res): print("af1") return res @app.after_request def af2(res): print("af2") # return res return "出错了" if __name__ == '__main__': app.run()
报错信息:
# 返回结果
be1 be2 af2 af1
三、before_request应用
@app.before_request 在请求(request)进入视图函数之前执行
@app.before_request 也是一个装饰器,他所装饰的函数,都会在请求进入视图函数之前执行
request.path 是来读取当前的url地址如果是 /login 就允许直接通过 return None 你可以理解成通过放行
校验session中是否有user 如果没有的话,证明没有登录,所以毫不留情的 redirect("/login") 跳转登录页面
还有一个要提的 @app.before_first_request 它与 @app.before_request 极为相似或者说是一模一样,只不过它只会被执行一次
from flask import Flask from flask import request from flask import redirect from flask import session app = Flask(__name__) # type:Flask app.secret_key = "DragonFire" @app.before_request def is_login():
#白名单 if request.path == "/login": return None #验证session if not session.get("user"): return redirect("/login")
return None @app.route("/login") def login(): return "Login" @app.route("/index") def index(): return "Index" @app.route("/home") def home(): return "Login" app.run("0.0.0.0", 5000)
四、before_request应用
@app.after_request 在响应(response)返回客户端之前执行 , 结束视图函数之后
@app.after_request必须return返回上一层的参数environ,否则会报错
@app.after_request def foot_log(environ): if request.path != "/login": print("有客人访问了",request.path) return environ
五、用flask的实现一个简单的页面登录
基于before_request与after_request的验证登录
from flask import Flask,render_template,request,redirect,session app = Flask(__name__,template_folder='templates') app.secret_key = "sdsfdsgdfgdfgfh" @app.before_request def process_request(): if request.path=="/login": return None if not session.get("user_info"): return redirect("/login") return None @app.after_request def process_response(response): print(2222) return response @app.route("/login",methods=["GET","POST"]) def login(): if request.method=="GET": return render_template("login.html") else: # print(request.values) #这个里面什么都有,相当于body username = request.form.get("username") password = request.form.get("password") if username=="annie" and password=="123": session["user_info"] = username # session.pop("user_info") #删除session return redirect("/index") else: # return render_template("login.html",**{"msg":"用户名或密码错误"}) return render_template("login.html",msg="用户名或者密码错误") @app.route("/index",methods=["GET","POST"]) def index(): # if not session.get("user_info"): # return redirect("/login") return render_template("index.html") if __name__ == '__main__': app.run(debug=True)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!