在客戶端和服務器交互的過程當中,有些準備工做或掃尾工做須要處理,好比:在請求開始時,創建數據庫鏈接;在請求結束時,指定數據的交互格式。爲了讓>每一個視圖函數避免編寫重複功能的代碼,Flask提供了通用設施的功能,即請求鉤子。經過請求鉤子,咱們能夠對請求進行預處理(preprocessing)和後處理>(postprocessing)。shell
Flask的請求鉤子經過裝飾器實現,每一個鉤子能夠註冊任意多個處理函數,默認的五種請求鉤子以下:數據庫
鉤子 | 說明 |
---|---|
before_first_request | 註冊一個函數,在處理請求前運行 |
before_request | 註冊一個函數,在處理每一個請求前運行 |
after_request | 註冊一個函數,若是有未處理的一場拋出。會在每一個請求結束後運行 |
teardown_request | 註冊一個函數,即便有未處理的異常拋出,會在每一個請求介紹後執行。若是發生異常,會傳入異常對象做爲參數註冊到函數中 |
after_this_request | 在視圖函數內註冊一個函數,在這個請求結束後運行 |
假如咱們建立了三個視圖函數A、B、C,其中視圖C使用了after_this_request鉤子,那麼當請求A進入後,整個請求處理週期的請求處理函數調用流程如圖:flask
什麼是上下文?上下文至關於一個容器,它保存了程序運行過程當中的一些信息,它是當前環境的一個快照(snapshot)。 Flask中有兩種上下文,程序上下文(application context)和請求上下文(request context)。 程序上下文中包含了程序運行所必須的信息;請求上下文裏包含了請求的各類信息,好比請求的URL、HTTP方法等服務器
咱們知道,Flask將請求報文封裝在request對象中。按照通常的思路,若是咱們要在視圖函數中使用它,就得把它做爲參數傳入視圖函數,就像咱們接收URL變量同樣。但這樣就會致使大量的重複,並且增長了的程序的負擔。 不通常的是,咱們能夠從Flask導入一個全局的request變量,在視圖函數中直接調用request的屬性獲取數據。這是爲何?由於Flask會在每一個請求產生後後自動激活當前請求的上下文,激活請求上下文後,request被臨時設置爲全局可訪問。在每一個請求結束後,Flask就會銷燬對應的請求上下文。session
Flask提供的四個上下文全局變量以下: |變量名|上下文類別|說明| |:--:|:--:|:--| |current_app|程序上下文|指向處理請求的當前程序實例| |g|程序上下文|替代Python的全局變量用法,確保僅在當前請求可用,用於存儲全局數據,每次請求都會重設| |request|請求上下文|封裝客戶端發出的請求報文數據| |session|請求上下文|用於記住請求之間的數據,經過簽名的Cookie實現|app
請求進入時,Flask會自動激活請求上下文,此時程序上下文也被自動激活。請求處理完畢後,請求上下文和程序上下文也會自動銷燬。二者具備相同的生命週期。函數
Flask自動激活上下文的狀況:post
flask run
命令啓動程序時app.run()
方法啓動程序時@app.cli.command()
裝飾器註冊的flask命令時flask shell
命令啓動Python Shell時手動激活的方法:this
>>> from app import app >>> from flask import current_app >>> with app.app_context(): ... current_app.name 'app'
>>> from app import app >>> from flask import current_app >>> app_ctx = app.app_context() >>> app_ctx.push() >>> current_app.name 'app' >>> app_ctx.pop()
>>> from app import app >>> from flask import request >>> with app.test_request_context('/hello'): ... request.method 'GET'