用 Flask 來寫個輕部落格 (16) — MV(C)_Flask Blueprint 藍圖
目錄
前文列表
擴充套件閱讀
Blueprint 藍圖
Blueprint 藍圖是一種用來擴充套件已有 Flask 應用結構的方法,通過藍圖的思想我們能夠把自己的 Application 拆分成為不同的元件。通常,一個元件代表了 Application 的一個功能模組,我們稱之為一個藍圖,但本質上是由一些被註冊到這個藍圖中的檢視集所組成的。而且還可以在該藍圖中定義其獨有的模板檔案目錄(template_folder)和靜態檔案目錄(static_folder)。最後,將一個個這樣的藍圖 Register 到 Flask 的主 app 中,最終整合成為一個完整的 Application,所以藍圖在 Flask 中充當了 MVC 架構中的 Controller 角色。
定義一個藍圖
NOTE : 這裡只是一個輔助理解的例子,並不作用到專案中。
- vim admin_pages/admin.py
from flask import Blueprint
admin = Blueprint(
'admin',
'__name__',
template_folder='template/admin',
static_folder='static/admin',
url_prefix='/admin')
@admin.route('/')
def home ():
return render_template('home.html')
NOTE 1: 藍圖類
Blueprint
必須接收兩個引數 藍圖名(admin) 和 當前的包名(__name__)NOTE 2: 可選引數定義了該藍圖到那裡去尋找所需要的檔案(template_folder/static__folder)
NOTE 3: 由於指定了引數 template_folder 所以該藍圖的檢視函式 home() 不會到預設的 template/ 目錄下尋找模板檔案 home.html 而是到 template/admin/ 目錄下尋找 home.html
NOTE 4: 引數 url_prefix 會為 URL 新增上字首 admin,即:檢視函式 home() 的 URL 路由實際上是 /admin/ ,而不是 /
NOTE 5: 所以當我們在模板中使用 url_for() 函式時,傳入的引數就不是 url_for(‘home’) 了,而是 url_for(‘admin.home’) 或 url_for(‘.home’) 如果需要查詢的 URL 路由跟當前檢視函式是在同一個藍圖下的話。
註冊一個藍圖
需要將藍圖註冊到 Flask 的 app 中,該藍圖才能夠生效。
- main.py
from admin_pages import admin
app.register_blueprint(admin)
這就是定義一個藍圖並將該藍圖註冊到 app 中的過程。接下來我們就會將藍圖應用到 blog 專案中來。
建立藍圖 blog
- views.py
建立藍圖首先我們要在檢視函式的模組中使用 Blueprint class 來生成一個藍圖物件,使檢視模組程式設計藍圖模組。
from os import path
from flask import render_template, Blueprint
blog_blueprint = Blueprint(
'blog',
__name__,
template_folder=path.join('templates/blog'),
url_prefix='/blog')
由於為藍圖 blog 定義了新的模板檔案存放路徑,所以將該藍圖所需要的模板檔案都從 templates/ move 到 templates/blog/ 下。
將所有的 app.route() 修改為使用藍圖的路由定義,將檢視函式都註冊到藍圖中:
@blog_blueprint.route('/')
@blog_blueprint.route('/<int:page>')
def home(page=1):
"""View function for home page"""
- main.py
在if __name__ == '__main__':
之後將新建的藍圖物件 blog_blueprint 註冊到 app 中:
if __name__ == '__main__':
app.register_blueprint(blog_blueprint)
app.run()
現在藍圖 blog 將所有的檢視函式都搬離 app 註冊到藍圖 blog 中了,但是 app 物件作為入口不能夠沒有檢視函式,所以在為其定義一個根目錄檢視函式,並且重定向到藍圖 blog 的 home() 中:
from flask import Flask, redirect
@app.route('/')
def index():
return redirect(url_for('blog.home'))
NOTE: 這裡的 url_for 傳入了 blog.name 而不是 blog_blueprint.home 是因為 Flask 內部搜尋的關鍵字為藍圖的名字而不是藍圖物件的變數名。