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()
posted @ 2020-03-23 16:48  godlover  阅读(290)  评论(0编辑  收藏  举报