Flask框架(flask中的藍圖Blueprint)
1. 我們學習Flask框架,開始的時候是把所有的檢視函式等都寫在一個檔案中
我們在這單個檔案中可以定義路由、檢視函式、定義模型等等。
但這顯然存在一個問題:隨著業務程式碼的增加,將所有程式碼都放在單個程式檔案中,是非常不合適的。
這不僅會讓程式碼閱讀變得困難,而且會給後期維護帶來麻煩。
2. 問題怎麼解決呢
一個程式執行檔案中,功能程式碼過多。 讓程式碼實現模組化
嘗試用模組的匯入的方式解決
把一個檔案拆開,把檢視函式按照不同的功能進行劃分,分成不同的檔案,然後建立一個主檔案,在主檔案中。利用模組匯入的方法,
這是我的檔案目錄
可以在其他檔案裡面把檢視函式放出去,然後利用裝飾器傳入引數的方式進行在主檔案中把其他檢視的路由進行繫結
from flask import Flask from Blueprint_le.goods import get_goods from Blueprint_le.users import register # 迴圈引用,解決的方法,推遲一方的匯入,讓一方先完成 # 使用裝飾器的函式使用方法,解決模組分割的問題 app = Flask(__name__) app.route("/get_goods")(get_goods) app.route("/register")(register) @app.route("/") def index(): return "index page" if __name__ == '__main__': print(app.url_map) app.run()
3. 什麼是藍圖?
藍圖:用於實現單個應用的檢視、模板、靜態檔案的集合。
藍圖就是模組化處理的類。
簡單來說,藍圖就是一個儲存操作路由對映方法的容器,主要用來實現客戶端請求和URL相互關聯的功能。
在Flask中,使用藍圖可以幫助我們實現模組化應用的功能。
4.藍圖的執行機制:
藍圖是儲存了一組將來可以在應用物件上執行的操作。
註冊路由就是一種操作,當在程式例項上呼叫route裝飾器註冊路由時,這個操作將修改物件的url_map路由對映列表。
當我們在藍圖物件上呼叫route裝飾器註冊路由時,它只是在內部的一個延遲操作記錄列表defered_functions中添加了一 個項。當執行應用物件的 register_blueprint() 方法時,應用物件從藍圖物件的 defered_functions 列表中取出每一項,即 呼叫應用物件的 add_url_rule() 方法,這將會修改程式例項的路由對映列表。
5.藍圖的使用
(1)建立藍圖物件
'''Blueprint必須指定兩個引數,admin表示藍圖的名稱,__name__表示藍圖所在模組''' admin = Blueprint('admin',__name__)
(2) 註冊藍圖的路由
@admin.route('/') def admin_index(): return 'admin_index'
(3) 在程式中註冊該藍圖
app.register_blueprint(admin,url_prefix='/admin')
6.藍圖的使用例子
以目錄的形式定義藍圖以及藍圖裡面模板目錄的處理
1. 首先我的目錄結構和我的程式和模板存放的目錄為:
2. 使用目錄分割,在cart目錄裡面的_ _ init _ _.py裡面建立藍圖,並且要把檢視載入進來
from flask import Blueprint '''建立藍圖 修改模板路徑為當前templates的路徑,還有一個設定靜態的目錄static_folder''' app_cart = Blueprint("app_cart", __name__, template_folder="templates") '''在__init__.py執行的時候,把檢視載入進來,讓藍圖與應用程式知道有檢視的存在''' # Blueprint_le.cart.views : 從路徑裡面的views.py匯入get_cart檢視函式 from Blueprint_le.cart.views import get_cart
3. 在views.py裡面使用藍圖,定義檢視函式,
定義模板 cart.html存放在cart裡面的templates下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>cart page</h1> </body> </html>
views.py
from flask import render_template from Blueprint_le.cart import app_cart @app_cart.route("/get_cart") def get_cart(): return render_template("cart.html")
4.不使用目錄的分割形式也可以,例如建立order.py,建立藍圖
from flask import Blueprint '''建立一個藍圖的物件,藍圖就是一個小模組的抽象的模組''' app_orders = Blueprint("app_orders", __name__) @app_orders.route("/get_orders") def get_orders(): return "get orders page"
5.然後建立一個main.py在裡面實現主要的程式碼:
from flask import Flask from Blueprint_le.orders import app_orders from Blueprint_le.cart import app_cart app = Flask(__name__) '''註冊藍圖 , url_prefix:給訪問的路徑加一個字首''' app.register_blueprint(app_orders, url_prefix="/orders") app.register_blueprint(app_cart, url_prefix="/cart") @app.route("/") def index(): return "index page" if __name__ == '__main__': # 打印出所有的路由 print(app.url_map) app.run(debug=True)
6. 首先可以訪問 沒有使用目錄分割的orders, 執行程式,瀏覽器訪問 127.0.0.1:5000/orders/get_orders
然後可以訪問使用目錄分割的cart,瀏覽器訪問 127.0.0.1:5000/cart/get_cart
7. 如果藍圖裡面的小目錄裡面沒有找到模板,則會去頂級的templates的目錄裡面去找
如果在藍圖的小目錄的templates的模板和總的templates的模板重名的話,則會使用總的templates裡的模板