flask的请求扩展,错误处理,标签和过滤器,中间件以及cbv的写法
flask的请求扩展(类似于django的中间件)
from flask import Flask,request
app = Flask(__name__)
# 相当于django中的process_request,再执行响应函数
@app.before_request
def before1(*args, **kwargs):
print(args, kwargs)
print("这是before1")
# return "ok"
@app.before_request
def before2():
print("这是before2")
# 整个项目启动的第一次,刷新不会执行
@app.before_first_request
def before_first_request():
print("这个是启动项目的第一次")
# 相当于django中的proces_response
@app.after_request
def after1(response):
print("after的参数", response)
print("这是after1")
return response
@app.after_request
def after2(response):
print("这是after2")
return response
@app.route("/")
def index():
print("这是响应函数!")
return "ok"
if __name__ == '__main__':
app.run()
图解:
总结执行顺序:
1.before_request 请求没经过响应函数的时候,会执行before_request装饰的函数,谁先注册谁先执行,只要有一个函数有返回值,后面所有的before_request都不会执行,且响应函数也不会执行,但是不会影响after_request的
2.after_request是在before_request与响应函数执行后执行,必须接收响应参数,同时也要把响应返回,执行是谁先注册后执行
3.before_first_request,当项目启动时,接收到的第一个请求,就会执行before_first_request装饰的函数,执行顺序也是谁先注册,先执行
flask的错误处理
from flask import Flask, render_template
app = Flask(__name__)
# 错误处理一
@app.teardown_request
def teardown(e):
print(e)
print("这是teardown_request")
# 错误处理2
@app.errorhandler(500)
def error_500(e):
print(e)
return "服务器出现错误"
@app.errorhandler(404)
def error_404(e):
print(e)
return render_template("404.html")
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
app.run()
总结:
1 teardown_request,一旦遇到错误就会执行,并且把错误传递给teardown_request装饰的函数, 没有错误也会执行,但是是错误为None,并不能处理错误,只能记录
2 errorhandle 可以捕获错误,并且对错误做出响应,返回给用户,如果你要用errorhandler你必须指定他捕获哪种类型的错误,就必须传错误码,然后就返回值,返回给用户
图解:
flask的标签和过滤器
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
# 相当于django中的标签
@app.template_global()
def get_sb(a1, a2):
return a1 + a2
# 相当于django中的过滤器,第一个参数是你要过滤的那个值
@app.template_filter()
def get_something(a1, a2, a3, a4):
return a1 + a2 + a3 + a4
if __name__ == '__main__':
app.run()
图展:
中间件(重写__ call_ _方法)
from flask import Flask
app = Flask(__name__)
app.debug = True
class MyMiddleware:
def __init__(self, old_wsgi_app):
self.old_wsgi_app = old_wsgi_app
def __call__(self, environ, start_response):
print("开始")
ret = self.old_wsgi_app(environ, start_response)
print("结束")
return ret
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
app.wsgi_app = MyMiddleware(app.wsgi_app)
app.run()
图展:
cbv写法
基础版
from flask import Flask,views,url_for
app = Flask(__name__)
def tt(func):
def inner(*args,**kwargs):
print("111。")
rv = func(*args,**kwargs)
print("222。")
return rv
return inner
class Index(views.View):
methods = ["GET"] #规定哪些请求方式可以请求我这个路由
decorators =[tt,] #这个是给 我们的响应添加装饰器
def dispatch_request(self):
return "ojbk"
app.add_url_rule("/index",view_func=Index.as_view(name="index"),endpoint="index1")
# 为什么要给as_view传递name= "index",
#1 as_view再语法就要你传,
#2 他作用Index.as_view(name="index")他返回是的view这个函数对象,我们传递name="index"是给view的__name__改变名字。如果不传,我没有办法通过名字来找路由的映射关系,因为都是”view“
常用版
from flask import Flask,views,url_for
app = Flask(__name__)
def tt(func):
def inner(*args,**kwargs):
print("111。")
rv = func(*args,**kwargs)
print("222。")
return rv
return inner
class Login(views.MethodView):
methods = ["GET","POST"] # 规定哪些请求方式可以请求这个路由
#decorators = [tt, ] # 这个是给响应添加装饰器
def get(self):
return "get"
def post(self):
return "post"
app.add_url_rule("/login",view_func=Login.as_view(name="login"))
#实现方法是重写了dispatch_request,通过请求方法,来找到当前类中的函数。
if __name__ == '__main__':
app.run()