Flask 基礎範例 - jenhaoyang/backend_blog GitHub Wiki

規劃Flask檔案架構

對於大型的Flask專案,將專案以packages來分類是個好方法(module:pythion程式檔 packages:放置module的資料夾)。
本專案結構如下:
flask_project: flask相關程式的資料夾
____templates: 存放html檔的資料夾
____static: 存放css檔的資料夾

instance:這個資料夾不進行版控!!專門用來存放機敏資料,或是db資料
test:包含測試modules資料夾

讓Flask專案可安裝化(建議在專案開始就規劃使用)

可安裝化表示你可以讓你的project像是安裝flask一樣用pip在你的python virtual environment安裝 可安裝化有以下好處

  1. 安裝化前你必須在flask的資料夾才能用flask或是python叫起你的flask專案,安裝化後flask和python可以在任何地方呼叫專案
  2. 可以用wheel檔管理你的專案環境
  3. 測試工具可以建立和專案隔離的環境
    setup.py

注意!!!:setup.py和MANIFEST.in要跟flask專案資料夾同一層,而不是在專案資夾裡免面

環境變數與啟動Flask

Linux或是Mac:

export FLASK_APP=flask_project
export FLASK_ENV=development
flask run

Windows cmd:

set FLASK_APP=flask_project
set FLASK_ENV=development
flask run

Windows powershell:

$env:FLASK_APP = "hello" $env:FLASK_ENV=development
flask run

Host IP設定, 127.0.0.1與0.0.0.0差別

產生Flask實體

Flask應用程式的核心就是Flask class的實體,所有的設定都會在這個class裡。為了顧及未來程式擴張,我們部會在global區建立Flask實體,我們將使用一個function產生flask實體,這個function我們將寫在flask_project底下的__init__.py裡面

設定和存取Database

本範例使用SQLite, 對於大型程式, 選則其他資料庫的效能會比較好。

連接資料庫

首先我們要跟資料庫連線,關於跟db的連線我們寫在db.py裡面 接下來我們需要建立table,table必須在程式第一次被啟動的時候建立,這裡我們用純SQL語法建立table並且寫在schema.sql

註冊close_db 和init_db_command function

close_db 和init_db_command這兩個function必須告訴flask,否則不會被flask調用, 註冊方式我們寫在db.py裡面

執行init-db指令

現在init-db指令已經被註冊,記得先設定環境變數FLASK_APP, FLASK_ENV,而且跟flask_project同一層資料夾,下flask init_db就可以初始化資料庫

Blueprints和Views

View function代表的是你用來回應request的function, 而view function的回傳值Flask會把它變成回應request的response

建立Blueprints

Blueprints是由一群相關的view function所組成,可以用來分類view function。
相較於之前view function直接註冊到flask app(也就是@app.route), blueprints的使用方法是view function註冊到blueprint之下,blueprint之後再註冊到flask app之下。
下面我們將用到兩個blueprint,一個用於 authentication functions(auth.py),另一個用於部落格貼文功能()。

增加view到Blueprint之下

首先我們auth Blueprint新增一個註冊用的view function(在auth.py),使用者會看到一個表單,將資料填寫後可以提交表單。表單會檢查使用者填入的資料,如果不合規定會顯示錯誤訊息並且要求使用者重填,成功則產生新的使用者並且進入登入的頁面

之後我們新增登入 view,步驟跟註冊view類似

Endpoints and URLs

Endpoints and URLs

編寫前端HTML:使用Template

編寫每個網頁共同的HTML:Basic Layout

網站的每一頁都有一些共同的地方,例如登入的使用者,利用Basic Layout讓每一頁都可以共用這些HTML,不必重複寫。編寫在base.html

註冊頁面和登入頁面

分別寫在register.html, login.html

編寫CSS:Static Files

美化網站用的CSS將會放在static資料夾,編寫在style.css

Blog BluePrint

定義部落格相關view function在blog.py,和auth不同的是,部落格的url前面沒有前綴。由於其他頁面也有可能用到重新導向到index頁面,為了方便起見使用add_url_rule('/', endpoint='index')如此一來'/'就會直接導向到index頁面

create

跟register 很像。在create view function前面加上login_required 來檢查使用者已經登入

Update

update和delete都會需要取得部落格文章,所以建立一個get_post來取得部落格文章避免程式重複。

撰寫測試程式

注意!!!:雖然測試放在最後一節才講,但是未來應該邊開發邊寫測試程式
測試程式資料夾跟flask專案同一層,而不是在flask專案裡。建立一個conftest.py來設定測試用的flask參數,以及data.sql來建立測試用的資料庫

Fixtures

在conftest.py中,包含設定用的函式fitures,每一個測試都會用到他們。測試用的Python module會以test_為名稱開頭,測試function也會以test_為名稱開頭 app這個fitures函式會產生flask實體並且將測試參數傳入

部署

建置與安裝

當你想要部署你的應用程式時,你需要建立一個distribution file。Python目前標準的distribution 格式是wheel,附檔名.whl。首先先安裝wheel
pip install wheel
用Python 呼叫setup.py可以讓你有多的command line tool來處理build相關的事情。利用bdist_wheel來建立wheel distribution file。
隨後你會看到一個檔案在新生成的資料夾dist
dist/flaskBlog-1.0.0-py3-none-any.whl
複製這份文件到另一台機器上,建立新的virtualenv,使用pip 安裝
pip install flaskBlog-1.0.0-py3-none-any.whl
由於這是另一台機器所以你必須執行init-db來建立資料庫
flask如果發現自己被安裝(在非editable mode)會自動建立instance 資料夾在venv/var/flaskBlog-instance set FLASK_APP=flaskBlog flask init-db

設定Secret Key

文章開始由提到SECRET_KEY應該是一段隨機的bytes,我們可以藉由下面的指令產生隨機bytes
python -c 'import os; print(os.urandom(16))'
在 instance folder建立config.py並且設定SECRET_KEY
SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'

執行Production Server

在正式環境下不應該用flask run,我們可以使用其他WSGI server例如gunicorn

參考
pallets/flask
Flask tutorial Flask 全域變數g