1. 程式人生 > >Flask 學習筆記(一)

Flask 學習筆記(一)

req unicorn world 全局變量 migrate mod 傳輸數據 ica function

一、Web 服務器與 Web 框架

首先明確一下,要運行一個動態網頁,我們需要

  1. 一個 Web 服務器來監聽並響應請求
  2. 一個 Web 應用來處理請求,生成響應

其中 Web 服務器通常都是別人已經實現好了的,它通過定義好的接口與我們編寫的 Web 應用通信。WSGI 就是一個統一的 Web 服務器接口標準,如果我們按照 WSGI 編寫 Web 應用,那麽它就能在任何符合該標準的服務器上運行,例如 Gunicorn 和 uWSGI + nginx。(對比一下 Java 的 Servlet,按照 Servlet 規範編寫的應用,都能運行在任何 Servlet 容器上,例如 Tomcat 和 Jetty,Servlet 容器就相當於 WSGI 服務器)

可是 WSGI 仍然比較底層,直接照著它寫太麻煩,於是就有了 Web 框架,Python 知名的就是 Flask 和 Django,Java 對應的是 Spring MVC. 但是 Flask 和 Django 都有內置服務器用於測試,而 Spring MVC 沒有,倒是 Spring Boot 可以使用內嵌的 tomcat 容器。

二、Flask

Flask 是一個微框架,“微”是指它的核心非常小,任何可選的功能都不包括在內。但是 Flask 社區提供了豐富的拓展插件,你可以通過選擇需要的插件來實現你想要的功能。

中間略過 n 萬字。。。

三、上下文 Context

1. 請求上下文 Request Context

Java 的 Spring MVC 將請求作為方法參數傳入,而且要求參數必須映射到某個類型或者某個 model 上。
Flask 的處理方式與之不同,它提供了一個全局代理對象——request,只要是在請求從開始到結束的過程中,都可以直接通過這個 request 訪問 HTTP 請求的各種參數。

請求上下文在請求開始時被壓入棧,這時 request 對象才可用,在請求結束後會立即被 pop 出來。

2. 應用上下文 Application Context

一個 app,就是一個 Flask 實例,通過 app = Flask(__name__) 創建。

在請求到來時,除了請求上下文被入棧,還有應用上下文也會被入棧。

請求結束時,它先 pop 出請求上下文,然後是應用上下文。

也就是說在請求過程中,應用上下文是可用的,這時可以通過 current_app 訪問當前 app 的相關數據。

疑問

  1. 在 flask 初始化時,我們不是已經通過 app = Flask(__name__) 創建了一個 app 實例了麽?直接用它不行麽?

這是因為所有的 flask 模塊都需要在 app 對象中註冊,在其它模塊導入 app 會出現循環導入的問題。

3. g 對象

g 對象,名稱來源於 global,保存在應用上下文中,指應用上下文中的全局變量。

應用上下文只是對當前 app 的一個代理,它的生命周期和請求上下文相同,因此 g 顯然也只存在於當前請求過程中,不能用於跨請求傳遞數據。

4. session 對象

session 位於 請求上下文中,但是它的內容會被保存到 cookie 中,發送到客戶端。每次收到請求時又會從 cookie 中加載它。因此它可用於跨請求傳輸數據。

但是 session 不是安全的數據保存方式,只適合存放非敏感數據。

四、插件

  1. python-dotenv:配置文件
  2. flask_wtform:表單
  3. flask-login:登錄與權限驗證
  4. flask-sqlalchemy + flask-migrate:數據庫
  5. flask-restplus:restful api
  6. flask-SocketIO:websocket

四、使用 blueprint(藍圖)

入門級 flask app 都是單文件應用,當復雜度上升,我們可以把單文件應用分成多個文件,比如:views.py、models.py、forms.py、errors.py。

但是如果項目繼續增大,各個文件也會漸漸變得難以維護。views.py 中各種功能的視圖函數混在一起,models.py 和 forms.py 也是。顯然我們可以按功能,繼續分割這幾個代碼文件。

blueprint 就是用於應對大型項目開發的功能,使用它可以對上述的文件按功能做進一步的拆分。

藍圖使用起來就像應用當中的子應用一樣,可以有自己的模板,靜態目錄,有自己的視圖函數和URL規則,藍圖之間互相不影響。但是它們又屬於應用中,可以共享應用的配置。

實際上 BluePrint 類的使用也幾乎和 Flask 一模一樣。差別只是 BluePrint 最後還需要在 Flask 實例中註冊:app.register_blueprint(<blue_print_obj>).

註意事項

  1. url_for 的第一個參數 endpoint,是 view function 的名稱,不是 route 路徑!
    • 使用 blueprint 時,endpoint 為 藍圖名稱.視圖函數名稱
  2. 讀取資源文件:資源文件可以放在 data 文件夾下,使用 flask.open_resources("data/<file_name>", mode="rb") 讀取資源文件。
    • 不放在 static 下的原因是,該目錄內的文件是可以直接通過 URI /static/<file_path> 訪問的,是公開的。我們一般不希望用戶直接訪問這種資源文件。

鏈接

  • flask
  • the-flask-mega-tutorial
  • flask的上下文疑問 current_app, g, session, request?
  • Flask的g對象,範圍是什麽?
  • Modular Applications with Blueprints

Flask 學習筆記(一)