在項目啓動後,接收到的第一個請求,就會執行,before_first_request裝飾的函數的執行順序是誰先註冊誰先執行html
請求沒有通過響應函數的時候就會執行before_request裝飾的函數,執行順序是誰先註冊誰先執行,若是被裝飾的函數有返回值,後面註冊的都不會執行,響應函數也不會執行,可是不會影響after_request執行django
在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()
一旦遇到錯誤就會執行傳遞給裝飾的函數,沒有錯誤也會執行,可是錯誤爲None,不能處理錯誤,只能記錄錯誤app
能夠對錯誤進行處理,而且作出相應給用戶,必需要傳錯誤狀態碼,只能傳一個值函數
裝飾函數能夠返回一個值,也能夠返回一個html頁面post
至關於Django的標籤,能夠不用在響應函數中傳值給html頁面,html能夠直接使用裝飾的函數名url
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()
路由綁定給類的方式,須要導入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')