Flask重構-使用工廠方法和藍圖
雖然初步開發的時候可以不用管結構,全部程式碼都塞在一起就好,但是遇到要擴展或是測試的時候問題就出現了,很多潛在的問題在程式擴展的路上會出現,增加很多時間成本。而我自己也想練習一下寫測試,有好的結構才能快速切換測試和開發的環境,剛好藉由自己的這個小project來玩玩看
結構
以下是重構後的資料結構
code
都拆開放在專屬的py
檔案裡了
app
資料夾是放Flask
主程式,也可以換成其他名子app/main
底下放的是views
(update
,delete
,add
之類的url
)app/templates
存放各個頁面的html
app/tests
放測試app
底下放command
(建資料庫,新增帳號密碼之類的)以及models
(放資料庫的models
)/
根目錄放main.py
用來呼叫app
裡的create_app()
來建立app
,這個是工廠方法,下面會提到
工廠方法(Factory pattern)
為了讓程式可以建立多個instance
,以便Unit test
(因為為了提高測試覆蓋度,有時候必須在不同的的設定下執行程式)。單instance
建立後沒辦法再修改設定,所以需要多個instance
解決方法是延遲建立instance,建立過程移至工廠方法,這裡放在app/__init__.py
(官方文件寫得超簡短…用處有限🤦♂️只知道db
要放在create_app()
)
工廠方法要配合藍圖(blueprint)才能建立路由和自訂
404
頁面
藍圖
- 藍圖: 放在
app/main/__init__.py
- 由於換成工廠模式來建立
instance
,建立後才能使用app.route
,但已經無法定義路由了,也就是在create_app()
裡定義藍圖好定義路由 - 藍圖中定義路由和錯誤處理程式處於休眠狀態,只有註冊(
register
)到應用程式上才成為他的一部分 - 可以在單個檔案中定義,也可以用結構化方式在多個
module
裡建立,為了方便直接在app/main
裡建立一個blueprint
,包含views
和errors
- 定義路由的時候要寫上藍圖的名稱,因為是由藍圖提供,而非
app.route
,這裡是@main.route()
- 使用藍圖時,
url_for()
裡的參數不再是直接寫上路由路徑的名子,例如url_for('index')
。而是要加上藍圖的名稱變為url_for('main.index')
這是為了在不同藍圖中使用同樣的路徑名 - 當同一個藍圖重定向(
redirect
)的時候可以簡化寫法變為url_for('.index')
,跨藍圖的時候就得加上藍圖名
設定檔
由於不同的階段會有不同的設定以及參數,所以需要設定檔來定義每個階段需要的設定,以便快速切換。例如開發、測試、和部署,都需要不同的設定以及參數,這時有設定檔就可以隨意切換,不須手動調整(自動就是爽)
這裡我是放在app/config.py
,簡單設定一下不同環境的參數
SECRET_KEY
等一些機密資訊可以用環境變數導入,更安全,為了方便,而且沒有機密,所以就直接寫入
切記不要把密碼以及機密資訊寫在版本控制的設定檔中
上面程式碼中也可以看到SQLALCHEMY_DATABASE_URI
在development
和testing
中是不同的值,這樣可以在不同環境中使用不同的資料庫,以免原本的資料庫被覆寫
啟動
- 重構後在根目錄建立
.flaskenv
讓flask
知道哪個是啟動的py
檔案
FLASK_APP=main.py
Flask重構-使用工廠方法和藍圖
https://f88083.github.io/2024/01/09/Flask重構-使用工廠方法和藍圖/