1. 程式人生 > >用 Flask 來寫個輕部落格 (16) — MV(C)_Flask Blueprint 藍圖

用 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 內部搜尋的關鍵字為藍圖的名字而不是藍圖物件的變數名。