淺談 Flask Blueprint 使專案更加方便管理和維護
2022-12-01 21:27:45
# 淺談 Flask Blueprint 使專案更加方便管理和維護
## 什麼是 Blueprint 能幫助我們做什麼?
* Factor an application into a set of blueprints. This is ideal for larger applications; a project could instantiate an application object, initialize several extensions, and register a collection of blueprints.
* Register a blueprint on an application at a URL prefix and/or subdomain. Parameters in the URL prefix/subdomain become common view arguments (with defaults) across all view functions in the blueprint.
* Register a blueprint multiple times on an application with different URL rules.
* Provide template filters, static files, templates, and other utilities through blueprints. A blueprint does not have to implement applications or view functions.
* Register a blueprint on an application for any of these cases when initializing a Flask extension.
簡單來說,當專案隨著架構越來越龐大,如果把程式都寫在同一個主程式裡面,會造成管理非常困難
,所以使用 **Flask Blueprint** 可以把每一個項目分離出來,要修改和維護就方便許多。
舉例在自製的圖書館專案中,把每個網頁和 api 的 route 集中在 app.py,看起來非常雜亂,不好管理。
```
myapp
├─ static
├─ templates
└─ app.py
```
```python
from flask import Flask, render_template
app = Flask(__name__)
# 首頁
@app.route("/")
def index():
return render_template("index.html")
# 會員
@app.route("/member")
def signig():
return render_template("member.html")
# 書本api
@app.route("/api/book")
def api_book():
return {"key" : "book"}
# 作者api
@app.route("/api/authors")
def api_authors():
return {"key" : "author"}
# 書本頁面
@app.route("/book")
def list():
return render_template("book.html")
# 尋找書本頁面
@app.route("/book/<int:id>")
def getItem(id:int):
return render_template("content.html",id=id)
# 作者首頁
@app.route("/authors")
def authors_list():
return render_template("authors.html")
# 尋找作者頁面
@app.route("/authors/<int:id>")
def authors_getItem(id:int):
return render_template("detail.html",id=id)
app.run(host="127.0.0.1",port=3050,debug=True)
```
## 使用 Blueprint 看起來會怎樣?
舉例先把 api 跟 app.py 分開來,這樣修改內容起來就方便許多。
```
myapp
├─ api/
| ├─ books_api.py
| └─ authors_api.py
├─ static
├─ templates
└─ app.py
```
## 第一步 : 創建 Flask Blueprint
### 首先先匯入 Blueprint 套件
```python
from flask import Blueprint
```
### 定義創建的 Blueprint 名字
```python
select_books = Blueprint("select_books",__name__)
```
### 使用的定義 Blueprint 的 route
```python
@select_books.route("/api/book")
def api_book():
return {"key" : "book"}
```
```python
from flask import Blueprint
select_books = Blueprint("select_books",__name__)
# 書本api
@select_books.route("/api/book")
def api_book():
return {"key" : "book"}
```
### 註冊 Flask Blueprint
```python
from api.books_api import select_books
app.register_blueprint(select_books)
```
相同的做法分開另一個 **api** 後,之後管理和維護相關 **api** 程式就簡單許多了。
```python
from flask import Flask, render_template
from api.authors_api import select_authors
from api.books_api import select_books
app = Flask(__name__)
# 首頁
@app.route("/")
def index():
return render_template("index.html")
# 會員
@app.route("/member")
def signig():
return render_template("member.html")
# 書本頁面
@app.route("/book")
def list():
return render_template("book.html")
# 尋找書本頁面
@app.route("/book/<int:id>")
def getItem(id:int):
return render_template("content.html",id=id)
# 作者首頁
@app.route("/authors")
def authors_list():
return render_template("authors.html")
# 尋找作者頁面
@app.route("/authors/<int:id>")
def authors_getItem(id:int):
return render_template("detail.html",id=id)
app.register_blueprint(select_authors)
app.register_blueprint(select_books)
app.run(host="127.0.0.1",port=3050,debug=True)
```
## Blueprint 設定參數說明
```python
from flask import Blueprint
example_blueprint = Blueprint('example_blueprint', __name__)
```
仔細說明 **Blueprint** 參數說明,第一個參數是說明 **Blueprint** 的名稱,第二個參數 **__name__** 是導入 **Blueprint** 的名稱,**Flask** 使用它來定位 **Blueprint**。
Blueprint 提供其他可選參數設定路徑
* **static_folder:** the folder where the Blueprint’s static files can be found
* **static_url_path:** the URL to serve static files from
* **template_folder:** the folder containing the Blueprint’s templates
* **url_prefix:** the path to prepend to all of the Blueprint’s URLs
* **subdomain:** the subdomain that this Blueprint’s routes will match on by default
* **url_defaults:** a dictionary of default values that this Blueprint’s views will receive
* **root_path:** the Blueprint’s root directory path, whose default value is obtained from the Blueprint’s import name
```python
app.register_blueprint(simple_page, url_prefix='/pages')
```
```python
simple_page= Blueprint('simple_page', __name__, url_prefix='/parent')
```
## 進階 Blueprint 設定
這邊介紹 **url_prefix** 的使用方法,分離 **authors** 和 **books** 的網頁 **route**。
```
myapp
├─ api/
| ├─ books_api.py
| └─ authors_api.py
├─ controllers/
| ├─ authors.py
| └─ books.py
├─ static
├─ templates/
| ├─ authors/
| | ├─ authors.html
| | └─ detail.html
| ├─ books/
| | ├─ book.html
| | └─ content.html
| ├─ index.html
| └─ member.html
└─ app.py
```
```python
from flask import Blueprint,render_template
authors_ctrlr = Blueprint("authors", __name__)
# 作者首頁
@authors_ctrlr.route("/")
def authors_list():
return render_template("authors/authors.html")
# 尋找作者頁面
@authors_ctrlr.route("/<int:id>")
def authors_getItem(id:int):
return render_template("authors/detail.html",id=id)
```
在 **templates** 裡建立了兩個資料夾 **authors** 和 **books** ,所以這邊 **render_template** 位置選擇相對的地方,在 **route** 的部分會在 **app.py** 會利用 **url_prefix** 裡設定網址路徑。
### 註冊和引入 Blueprint
```python
from controllers.books import books_ctrlr
from controllers.authors import authors_ctrlr
app.register_blueprint(authors_ctrlr, url_prefix="/authors")
app.register_blueprint(books_ctrlr, url_prefix="/books")
```
這邊 **url_prefix** 分別設定 **/authors** 和 **/books** , 所以相對的在網址填入就會分別引導到 **authors** 和 **books** 的 **html route** 上面。
**app.py** 就分離了 **authors** 和 **books** 的網頁。
```python
from flask import Flask, render_template
from api.authors_api import select_authors
from api.books_api import select_books
from controllers.books import books_ctrlr
from controllers.authors import authors_ctrlr
app = Flask(__name__)
# 首頁
@app.route("/")
def index():
return render_template("index.html")
# 會員
@app.route("/member")
def signig():
return render_template("member.html")
app.register_blueprint(authors_ctrlr, url_prefix="/authors")
app.register_blueprint(books_ctrlr, url_prefix="/books")
app.register_blueprint(select_authors)
app.register_blueprint(select_books)
app.run(host="127.0.0.1",port=3050,debug=True)
```
### 執行程式
**首頁**
![image](wehelp-storage://b603bb5cb911d893c7814785ac21c0b1)
**book api**
![image](wehelp-storage://1815cd122d8056ca4a6ddcaf4bd7b61e)
**author api**
![image](wehelp-storage://d9e11fe2c5142d836f2220488b9d5957)
**book 網頁**
![image](wehelp-storage://398f6bd2bc353d39793cf883bcd94c88)
![image](wehelp-storage://589ac619db67eb1677314e89afb0e9e2)
**author 網頁**
![image](wehelp-storage://5528ecf69908db473a63fd0dd8da4888)
![image](wehelp-storage://7a666bfbf8b7b18919b56c7d58a8fdd7)
最後關於參數設定路徑的方法還有很多種,以下網址有提供相關的做法。
參考連結:
[https://flask.palletsprojects.com/en/2.2.x/blueprints/](https://flask.palletsprojects.com/en/2.2.x/blueprints/)
[https://realpython.com/flask-blueprint/](https://realpython.com/flask-blueprint/)
[https://www.freecodecamp.org/news/how-to-use-blueprints-to-organize-flask-apps/](https://www.freecodecamp.org/news/how-to-use-blueprints-to-organize-flask-apps/)
[https://medium.com/seaniap/python-web-flask-blueprints-解決大架構的網站-1f9878312526](https://medium.com/seaniap/python-web-flask-blueprints-%E8%A7%A3%E6%B1%BA%E5%A4%A7%E6%9E%B6%E6%A7%8B%E7%9A%84%E7%B6%B2%E7%AB%99-1f9878312526)
https://www.youtube.com/watch?v=SezbDCz0Ock&t=912s
點擊複製文章連結
X