flask中间件及CBV

flask请求扩展、中间件及CBV与蓝图

一、请求扩展(相似于Django中间件)

一、before_first_request

在项目启动后,接收到的第一个请求,就会执行,before_first_request装饰的函数的执行顺序是谁先注册谁先执行html

二、before_request

请求没有通过响应函数的时候就会执行before_request装饰的函数,执行顺序是谁先注册谁先执行,若是被装饰的函数有返回值,后面注册的都不会执行,响应函数也不会执行,可是不会影响after_request执行django

三、after_request

在before_request与响应函数执行后执行,必须接受响应参数response,而且要将响应参数response返回,执行顺序是谁先注册后执行flask

from flask import Flask, request

app = Flask(__name__)

#1执行响应函数以前,至关于django中的process_request
@app.before_request
def before1():
    print('before1')
    # 在before_request中返回后后续before_request与响应函数都不会执行了
    return 'ok'

@app.before_request
def before2():
    print('before2')

#after_request必须接收一个参数,参数为Response对象,并且必须返回
@app.after_request
def after1(response):
    print('after1')
    return response

@app.after_request
def after2(response):
    print('after2')
    return response

# 项目启动后接收到的第一个请求,所要执行的函数,这是整个项目的第一次,
@app.before_first_request
def first():
    print('first')

@app.route('/')
def index():
    print('响应函数')
    return 'ok'


if __name__ == '__main__':
    app.run()

四、teardown_request

一旦遇到错误就会执行传递给装饰的函数,没有错误也会执行,可是错误为None,不能处理错误,只能记录错误app

五、errorhandle(错误状态码)

能够对错误进行处理,而且作出相应给用户,必需要传错误状态码,只能传一个值函数

装饰函数能够返回一个值,也能够返回一个html页面post

六、template_global()

至关于Django的标签,能够不用在响应函数中传值给html页面,html能够直接使用装饰的函数名url

七、template_filter()

django中的过滤器,第一个参数是你要过滤的那个值,能够不用在响应函数返回值中传,页面能够直接使用,要与函数名同名,html中用 | 来划分过滤的第一个元素spa

from  flask import Flask,request,render_template

app  = Flask(__name__)
 @app.teardown_request def tear(e):
     print(e)
     print("我是teardown_request")

@app.errorhandler(500)
def error_500(e):
    print(e)
    return "我程序崩了,你下次来把"

@app.errorhandler(404)
def error_404(e):
    print(e)
    return render_template("404.html")

#至关于django中的标签。能够不用在响应函数返回值中传,页面能够直接使用要与函数名同名
@app.template_global()
def get_sb(a1,a2):
    return a1 + a2
#在html中的用法:{{get_sb(1,2)}}

#django中的过滤器,第一个参数是你要过滤的那个值,能够不用在响应函数返回值中传,页面能够直接使用,要与函数名同名
@app.template_filter()
def get_something(a1,a2,a3,a4):
    return a1+a2+a3+a4
#在html中的用法:{{1|get_something(2,3,4)}}


@app.route("/")
def index():
    print("我是响应函数")
    return render_template("index.html")


if __name__ == '__main__':
    app.run()

二、中间件

flask中的中间件本质是在执行wsgi_app的先后执行的叫作中间件code

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'ok'

class MyMiddleware:
    # 继承原来的wsgi_app
    def __init__(self, old_wsgi_app):
        self.old_wsgi_app = old_wsgi_app
    # 重写__call__方法实现中间件
    def __call__(self, environ, start_response):
        print('中间件在before以前的执行')
        ret = self.old_wsgi_app(environ, start_response)
        print('中间件在after以后的执行')
        return ret

if __name__ == '__main__':
    # app.__call__()
    # 源码中推崇这种写法
    app.wsgi_app = MyMiddleware(app.wsgi_app)
    app.run()

三、CBV

路由绑定给类的方式,须要导入views,CBV必须使用路由分发的方式绑定路由,而且路由中要给as_view传参name绑定别名,Index.as_view(name="index")他的做用是返回view对象,咱们传递name="index"是给view的__name__改变名字,若是不传,咱们无法经过名字来找路由的映射关系,由于都是viewhtm

类中设置属性 methods = ["GET"]   #规定哪些请求方式能够请求我这个路由

      decorators =[tt,]   #这个是给咱们的响应添加装饰器

一、若是类继承views.View就要用dispatch_request方法

from flask import Flask,views,url_for

app = Flask(__name__)
def tt(func):
   def inner(*args,**kwargs):
       print("你追到我。。")
       rv = func(*args,**kwargs)
       print("嘿嘿嘿。。。")
       return  rv
   return inner

class Index(views.View):
    methods = ["GET"] #规定哪些请求方式能够请求我这个路由
    decorators =[tt,]   #这个是给 咱们的响应添加装饰器
    # 若是是views.View就必须是dispatch_request函数
    def dispatch_request(self):
        return "ojbk"
# CBV必须用路由分发,也能够用endpoint作反向解析,endpoint要优先于name=
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“

二、若是类继承views.MethodView就是将dispatch_request方法拆分自定义get与post方法

from flask import Flask,views,url_for

app = Flask(__name__)
def tt(func):
   def inner(*args,**kwargs):
       print("你追到我。。")
       rv = func(*args,**kwargs)
       print("嘿嘿嘿。。。")
       return  rv
   return inner

class Login(views.MethodView):
    methods = ["GET","POST"]  # 规定哪些请求方式能够请求我这个路由
    #decorators = [tt, ]  # 这个是给 咱们的响应添加装饰器
    # 继承views.MethodView来作路由分发,重写dispatch_request经过请求方法,来找到当前类中的函数
    def get(self):
        print(url_for("index1"))
        return "get"
    def post(self):
        return "post"

app.add_url_rule("/login",view_func=Login.as_view(name="login"))

if __name__ == '__main__':
    app.run()

四、蓝图

用来划分目录与指定路由分发,防止循环导入问题

使用:

一、导入蓝图  from flask import Blueprint

二、在视图中注册蓝图  ord = Blueprint("order",__name__)

三、绑定路由用注册的蓝图名绑定路由  @ord.route("/order")

四、在init中注册蓝图  app.register_blueprint(order.ord)

user.py

# 导入蓝图
from flask import Blueprint

# 注册蓝图,user是起的别名,在init中注册的时候找到具体是哪一个的蓝图
us = Blueprint('user', __name__)
# 路由使用蓝图对象
@us.route('/user')
def user():
    return 'ok'

__init__.py

from flask import Flask

app = Flask(__name__)

# 导入要执行的函数
from app01 import user
# 注册蓝图
app.register_blueprint(user.us)

给单个蓝图加请求扩展直接在蓝图使用

@blog.before_request

若是给所有的蓝图都加上同一个请求扩展是在app中加

@app.before_request

在init注册的时候能够给蓝图加前缀,访问时须要加上前缀

app.register_blueprint(admin, url_prefix='/admin')
相关文章
相关标签/搜索