Flask-藍圖(blueprint)

藍圖 Blueprint

模塊化

隨著flask程序越來越復(fù)雜,我們需要對程序進行模塊化的處理,之前學(xué)習(xí)過python的模塊化管理,于是針對一個簡單的flask程序進行模塊化處理

簡單來說,Blueprint 是一個存儲視圖方法的容器,這些操作在這個Blueprint 被注冊到一個應(yīng)用之后就可以被調(diào)用,F(xiàn)lask 可以通過Blueprint來組織URL以及處理請求。

Flask使用Blueprint讓應(yīng)用實現(xiàn)模塊化,在Flask中,Blueprint具有如下屬性:

  • 一個項目可以具有多個Blueprint
  • 可以將一個Blueprint注冊到任何一個未使用的URL下比如 “/”、“/sample”或者子域名
  • 在一個應(yīng)用中,一個模塊可以注冊多次
  • Blueprint可以單獨具有自己的模板、靜態(tài)文件或者其它的通用操作方法,它并不是必須要實現(xiàn)應(yīng)用的視圖和函數(shù)的
  • 在一個應(yīng)用初始化時,就應(yīng)該要注冊需要使用的Blueprint

但是一個Blueprint并不是一個完整的應(yīng)用,它不能獨立于應(yīng)用運行,而必須要注冊到某一個應(yīng)用中。

Blueprint對象用起來和一個應(yīng)用/Flask對象差不多,最大的區(qū)別在于一個 藍圖對象沒有辦法獨立運行,必須將它注冊到一個應(yīng)用對象上才能生效

使用藍圖可以分為四個步驟

  1. 創(chuàng)建一個藍圖的包,例如users,并在__init__.py文件中創(chuàng)建藍圖對象
users=Blueprint('users',__name__)
  1. 在這個藍圖目錄下, 創(chuàng)建views.py文件,保存當(dāng)前藍圖使用的視圖函數(shù)
@admin.route('/')
def home():
    return 'user.home'
  1. users/init.py中引入views.py中所有的視圖函數(shù)
from flask import Blueprint
# 等同于原來在 manage.py里面的 app = Flask()
users=Blueprint('users',__name__)

from .views import *
  1. 在主應(yīng)用main.py文件中的app對象上注冊這個users藍圖對象
from users import users
app.register_blueprint(users,url_prefix='/users')

當(dāng)這個應(yīng)用啟動后,通過/users/可以訪問到藍圖中定義的視圖函數(shù)

運行機制

  • 藍圖是保存了一組將來可以在應(yīng)用對象上執(zhí)行的操作,注冊路由就是一種操作
  • 當(dāng)在app對象上調(diào)用 route 裝飾器注冊路由時,這個操作將修改對象的url_map路由表
  • 然而,藍圖對象根本沒有路由表,當(dāng)我們在藍圖對象上調(diào)用route裝飾器注冊路由時,它只是在內(nèi)部的一個延遲操作記錄列表defered_functions中添加了一個項
  • 當(dāng)執(zhí)行app對象的 register_blueprint() 方法時,應(yīng)用對象將從藍圖對象的 defered_functions 列表中取出每一項,并以自身作為參數(shù)執(zhí)行該匿名函數(shù),即調(diào)用應(yīng)用對象的 add_url_rule() 方法,這將真正的修改應(yīng)用對象的usr_map路由表

藍圖的url前綴

  • 當(dāng)我們在應(yīng)用對象上注冊一個藍圖時,可以指定一個url_prefix關(guān)鍵字參數(shù)(這個參數(shù)默認(rèn)是/)
image.png
  • 在應(yīng)用最終的路由表 url_map中,在藍圖上注冊的路由URL自動被加上了這個前綴,這個可以保證在多個藍圖中使用相同的URL規(guī)則而不會最終引起沖突,只要在注冊藍圖時將不同的藍圖掛接到不同的自路徑即可
  • url_for在使用時,如果要生成一個藍圖里面的視圖對應(yīng)的路由地址,則需要聲明當(dāng)前藍圖名稱+視圖名稱
url_for('users.home') # /users/home

注冊藍圖中的靜態(tài)文件的相關(guān)路由

和應(yīng)用對象不同,藍圖對象創(chuàng)建時不會默認(rèn)注冊靜態(tài)目錄的路由。需要我們在 創(chuàng)建時指定 static_folder 參數(shù)。

下面的示例將藍圖所在目錄下的static_users目錄設(shè)置為靜態(tài)目錄

# users/__init__.py,代碼:
user_blu = Blueprint("users",__name__,static_folder='static_users')

# 啟動文件 main.py,代碼:
from users import user_blu
app.register_blueprint(user_blu,url_prefix='/users')

現(xiàn)在就可以使用/admin/static_admin/ 訪問static_admin目錄下的靜態(tài)文件了 定制靜態(tài)目錄URL規(guī)則 :可以在創(chuàng)建藍圖對象時使用 static_url_path 來改變靜態(tài)目錄的路由。

image.png

下面的示例將為 static_admin 文件夾的路由設(shè)置為 /lib

admin = Blueprint("admin",__name__,static_folder='static_admin',static_url_path='/lib')
app.register_blueprint(admin,url_prefix='/admin')

設(shè)置藍圖中模版的目錄

藍圖對象默認(rèn)的模板目錄為系統(tǒng)的模版目錄,可以在創(chuàng)建藍圖對象時使用 template_folder 關(guān)鍵字參數(shù)設(shè)置模板目錄

創(chuàng)建藍圖中的模板目錄template_users :

image.png
admin = Blueprint('admin',__name__,template_folder='templates_users')
image.png

注:如果在 templates 中存在和 templates_users 有同名模板文件時, 則系統(tǒng)會優(yōu)先使用 templates 中的文件

調(diào)整session配置

分析SQLAlachemy的構(gòu)造方式可以發(fā)現(xiàn),初始化并非一定要傳遞app應(yīng)用對象到內(nèi)部,事實上它提供了init_app方法給我們后續(xù)調(diào)用。而 init_app 方法是flask框架要求任何的第三方組件都要實現(xiàn)這個方法。

init_app方法內(nèi)部就是要第三方組件開發(fā)者編寫一些使用當(dāng)前組建的默認(rèn)配置項以及把當(dāng)前組件設(shè)置成一個對象,加載到app對象內(nèi)部extensions字典才能讓開發(fā)者在flask框架內(nèi)部配置和使用當(dāng)前組件。

我們可以利用這種組件開發(fā)機制,那么把配置代碼抽離出去。

配置文件中:

import redis
from flask_sqlalchemy import SQLAlchemy
# 創(chuàng)建db對象
db = SQLAlchemy()
class Config(object):
    DEBUG = True
    SECRET_KEY = "*(%#4sxcz(^(#$#8423"
    # 數(shù)據(jù)庫鏈接配置:
    #數(shù)據(jù)類型://登錄賬號:登錄密碼@數(shù)據(jù)庫主機IP:數(shù)據(jù)庫訪問端口/數(shù)據(jù)庫名稱
    SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/flask_students"
    # 設(shè)置mysql的錯誤跟蹤信息顯示
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 打印每次模型操作對應(yīng)的SQL語句
    SQLALCHEMY_ECHO = True

    """把session保存到redis中"""
    # session存儲方式為redis
    # SESSION_TYPE="redis"
    # # 如果設(shè)置session的生命周期是否是會話期, 為True,則關(guān)閉瀏覽器session就失效
    # SESSION_PERMANENT = False
    # # 是否對發(fā)送到瀏覽器上session的cookie值進行加密
    # SESSION_USE_SIGNER = False
    # # 保存到redis的session數(shù)的名稱前綴
    # SESSION_KEY_PREFIX = "session:"
    # # session保存數(shù)據(jù)到redis時啟用的鏈接對象
    # SESSION_REDIS = redis.Redis(host='127.0.0.1', port='6379')  # 用于連接redis的配置

    SESSION_TYPE= 'sqlalchemy'  # session的存儲方式為sqlalchemy
    SESSION_SQLALCHEMY= db  # SQLAlchemy對象
    SESSION_SQLALCHEMY_TABLE= 'sessions'  # session要保存的表名稱
    SESSION_PERMANENT= True  # 如果設(shè)置為True,則關(guān)閉瀏覽器session就失效。
    SESSION_USE_SIGNER= False  # 是否對發(fā)送到瀏覽器上session的cookie值進行加密
    SESSION_KEY_PREFIX= 'session:'  # 保存到session中的值的前綴

啟動文件main.py,代碼:

from flask import Flask
from config import Config,db
from flask_session import Session

from flask import session

app = Flask(__name__,template_folder='templates')
app.config.from_object(Config)

# 把app加載到db對象中
db.init_app(app)

Session(app)

@app.route("/")
def index():
    return "ok"

@app.route("/set_session")
def set_session():
    """設(shè)置session"""
    session["username"] = "小明"
    return "ok"

if __name__ == '__main__':
    # db.create_all()
    print( app.url_map )
    app.run()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Flask藍圖提供了模塊化管理程序路由的功能,使程序結(jié)構(gòu)清晰、簡單易懂。下面分析藍圖的使用方法 假如說我們要為某所...
    楓林夕陽閱讀 27,456評論 3 13
  • 解釋1: 允許將應(yīng)用組織為模塊,每個模塊有自洽的 MVC,開發(fā)者做些工作可以使模塊間依賴盡可能少,必要時可以按 b...
    大詩兄_zl閱讀 2,343評論 1 1
  • 1,藍圖定義: Flask 用 藍圖(blueprints) 的概念來在一個應(yīng)用中或跨應(yīng)用制作應(yīng)用組件和支持通用的...
    曉可加油閱讀 910評論 0 0
  • 第二個理念弄明白自己想要做什么 在第二個理念中,作者提供了六個案例 1.弄明白自己正在做什么 2.召開一次高效的會...
    Justina_Fu閱讀 237評論 2 1
  • ?與Java不同的是,在kotlin中,類是沒有顯式的static方法和static成員變量的,都是通過伴生對象的...
    跳動的字符閱讀 1,730評論 0 0

友情鏈接更多精彩內(nèi)容