一. 從簡單的 Flask 開始
首先來看一個大家熟悉且單純的 Flask,運行 flask run
後,連線 http://127.0.0.1:5000/ 後,在網頁上會得到 foo 的字詞
app.py
from flask import Flask
import auth
app = Flask(__name__)
@app.route('/')
def index():
return 'foo'
if __name__ == "__main__":
app.run(debug=True)
1.當 Flask 架構越來越龐大…
但是隨著網站架構越來越龐大,把所有的 route 都放在 main.py 裡面,在維護上會有很大的困擾,所以我們開始試著把部分功能切到另外一個 py 檔案裡。
開始將 route 切出來,不再都集中在 app.py 內:
flask
├── app.py
└── userdata.py
app.py
from flask import Flask
import userdata
app = Flask(__name__)
@app.route('/')
def index():
return 'foo'
if __name__ == "__main__":
app.run(debug=True)
userdata.py
from app import app
@app.route('/auth')
def auths():
return 'auth'
運行 flask
$ export FLASK_APP=app.py
$ flask run
連線 http://127.0.0.1:5000/auth 會發生 Not Found 的錯誤
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
會發生這個原因,是因為 import 循環衝突的問題造成,如下圖當運行 flask run 過後,會 import userdata 而在 userdata 裡面又會回來 import app,造成一個無限迴圈。

2.當遇上 Circular Imports 問題
一樣的資料夾結構
flask
├── app.py
└── auth.py
app.py
from flask import Flask
import auth
app = Flask(__name__)
auth.init_app(app)
@app.route('/')
def index():
return 'foo'
if __name__ == "__main__":
app.run(debug=True)
auth.py
def init_app(app):
@app.route('/auth')
def auths():
return 'auth'
可以看到我們這次在 auth.py 裡面並沒有 from app import app
,而是寫了一個涵式 def init_app(app)
。當 app = Flask(__name__)
被準備好的時候,把 app 透過 auth.init_app(app)
的方式啟動 auth.py 裡面的路徑,這樣就可以避免無限循環的問題了!
Flask 運行
$ export FLASK_APP=app.py
$ flask run
連線 http://127.0.0.1:5000/auth 就會得到如預期的返回 auth 文字
二. 面對龐大架構,官方建議使用 Blueprints
Blueprints can greatly simplify how large applications work and provide a central means for Flask extensions to register operations on applications.
Modular Applications with Blueprints — Flask Documentation (1.1.x)
可使用 Flask Blueprints 將程式碼拆分成不同的模塊 (modules),Flask 並沒有強制規定切分的結構 (Architect),但常見的切分結構有以下兩者:
Flask 架構第一種:根據不同的功能建立專屬的 templates 和路徑。
ecommerce/
|
├── auth/
| ├── templates/
| | └── auth/
| | ├── login.html
| | ├── forgot_password.html
| | └── signup.html
| ├── __init__.py
| └── auth.py
|
├── cart/
| ├── templates/
| | └── cart/
| | ├── checkout.html
| | └── view.html
| ├── __init__.py
| └── cart.py
|
├── static/
| ├── logo.png
| ├── main.css
| └── generic.js
|
├── app.py
├── config.py
└── models.py
Flask 架構第二種:僅使用 Flask Blueprints 切分路徑,但 templates 統一放在主資料夾下的 templates 內。
ecommerce/
|
├── static/
| ├── logo.png
| └── main.css
|
├── templates/
| ├── auth/
| | ├── login.html
| | ├── forgot_password.html
| | └── signup.html
| └── cart/
| ├── checkout.html
| └── view.html
|
├── view/
| ├── auth.py
| └── cart.py
|
├── app.py
├── config.py
└── models.py
兩種結構方法各適合不同的情境使用,提供給大家參考
開始實作 Flask Blueprints 教學
1.環境設置
*注意:Blueprints 不需要額外安裝套件,我們會從 from flask import Blueprint
中引入即可。
此次的資料夾結構
/flask
├── /view
│ └── api.py
└── main.py
此次需的 requirements 套件,僅安裝了 flask 1.1.2 的版本
click==7.1.2
Flask==1.1.2
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
Werkzeug==1.0.1
2.開始建置 Flask Blueprints
1.設定 main.py 檔
首先使用 app.register_blueprint
註冊出新的 app,並且命名為 app2
檔案位置:flask/main.py
from flask import Flask, Blueprint
from view.api import app2
app = Flask(__name__)
@app.route('/')
def index():
return "Hello index"
app.register_blueprint(app2)
2. 設定 api.py 檔
就可以使用剛剛在 main.py 註冊出新的 app2,並使用 @app2.route()
來創造出新路徑
檔案位置:flask/view/api.py
from flask import Blueprint
app2 = Blueprint('app2', __name__)
@app2.route('/app2')
def show(page):
return "Hello Blueprint app2"
3. 運行 Flask
> export FLASK_APP=main.py
> flask run
並且連線 http://127.0.0.1:5000/app2 就可以連到剛剛切出來的 app2 囉!
4. Blueprints 進階參數設定
▍常用的參數設定: url_prefix
app.register_blueprint(app2, url_prefix='/pages')
代表未來所有的 app2 所創建出來的路徑,前面網址都需要加上 pages,所以如果我們今天要連上剛剛創建的 @app2.route('/app2')
,網址是 http://127.0.0.1:5000/pages/app2
▍常用的參數設定: static_folder
、template_folder
app2 = Blueprint('app2', __name__, static_folder='static')
可以指定新註冊的 app2 使用的 static 位置
app2 = Blueprint('app2', __name__, template_folder='templates')
可以指定新註冊的 app2 使用的 template 位置
本篇參考的相關文章:
- Modular Applications with Blueprints — Flask Documentation (1.1.x)
- Flask Factory Pattern to set up your project. | by Felipe Florencio Garcia | ITNEXT
- Flask Blueprints — Complete Tutorial to fully understand how to use it! | by Felipe Florencio Garcia | Jun, 2020 | ITNEXT
- Use a Flask Blueprint to Architect Your Applications – Real Python
更多 Flask 教學相關閱讀:
▍關於 Flask 教學系列目錄:
▍關於 Flask 部署相關文章:
- 【Flask 教學系列】實作 GCP 部署 Flask + Nginx + uWSGI
- 第一集:實作 Dockerfile + flask 教學 (附GitHub完整程式)
- 第二集:實作 Dockerfile + nginx + ssl + flask 教學 (附GitHub完整程式)
- 第三集:實作 Docker-compose (Flask+Nginx+PostgreSQL)
- 【Flask 教學系列】實作 Flask + GitHub Action CI/CD
▍其他 Flask 相關教學:
- 【Flask教學系列】Flask 為甚麼需要 WSGI 與 Nginx
- 【Flask教學系列】Flask-SQLAlchemy 資料庫連線&設定入門 (一)
- 【Flask教學系列】Flask-JWT-Extended 實作
- 【Flask教學系列】實作 Flask CORS
- 【Flask教學系列】實作 Flask CSRF Protection
有關 Max行銷誌的最新文章,都會發佈在 Max 的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!