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')
相關文章
相關標籤/搜索