python之藍圖blueprint淺析

目錄

 背景

一、python中的藍圖

二、創建藍圖

三、藍圖的運行機制

四、藍圖的url前綴

五、註冊藍圖中的靜態文件的相關路由

六、設置藍圖中模版的目錄

七、調整session配置


 背景

由於我們現在的項目開發是一個相對於來說非常耗時間和精力的工程,如果我們將所有的Flask的請求方法都寫在同一個文件下的話,非常不便於我們的代碼的管理和後期的功能代碼的添加。
       如下示例:我們在一個文件中寫入多個路由,這會使代碼維護變得困難。

       如圖所示,如果我們將所有的請求方法寫在同一個處理文件下面的話,會導致我們的代碼顯得很沒有邏輯性,如果我們後期想要修改代碼或者添加新的代碼的話,就會顯得很尷尬,不知道如何的下手,此時就需要我們的所謂的藍圖來解決這個問題了,如果學過django的程序員可能瞭解過django中的app的作用了,沒錯,django中的app的主要作用就是將django的項目分成一個個單獨的app,然後將所有的app分配不同的處理功能,通過路由分配將它們連接成一個大的django項目,其實Flask中的藍圖和django中的app功能大同小異。

一、python中的藍圖

簡單來說,Blueprint 是一個存儲視圖方法的容器,這些操作在這個Blueprint 被註冊到一個應用之後就可以被調用,Flask 可以通過Blueprint來組織URL以及處理請求。

Flask使用Blueprint讓應用實現模塊化,在Flask中,Blueprint具有如下屬性:

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

但是一個Blueprint並不是一個完整的應用,它不能獨立於應用運行,而必須要註冊到某一個應用中。

Blueprint對象用起來和一個應用/Flask對象差不多,最大的區別在於一個 藍圖對象沒有辦法獨立運行,必須將它註冊到一個應用對象上才能生效。

二、創建藍圖

1. 我們首先創建一個主路由配置文件manage.py,該文件主要的作用就是啓動整個的Flask框架(項目),如圖所示

2. 接着,我們在manage.py的平級的目錄下創建兩個文件admin.py、user.py,我們大概看一下兩個文件中的內容:

      這兩個文件相當於django中的兩個app了,不同是django中的路由分配是將大的路由通過include分配給app的urls.py,而Flask是通過藍圖註冊的方式將藍圖添加到主app中,user.py,admin.py中主要是創建藍圖,然後爲創建的藍圖可以添加部分的路由配置。

3. 接着我們就可以在主路由文件manage.py中將我們創建的藍圖註冊到主app中了。

       最後我們配置好了以後,就可以實現我們的路由分層管理了,我們來試一下,運行主程序manage.py

       我們在瀏覽器中訪問我們所設置的路由

      

我們我請求的路由和我們所設置的返回值是一樣的,這樣我們就大概的完成了一個Flask的藍圖的註冊,實現了文件功能的分層次管理了。

三、藍圖的運行機制

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

四、藍圖的url前綴

  • 當我們在應用對象上註冊一個藍圖時,可以指定一個url_prefix關鍵字參數(這個參數默認是/)

 

  • 在應用最終的路由表 url_map中,在藍圖上註冊的路由URL自動被加上了這個前綴,這個可以保證在多個藍圖中使用相同的URL規則而不會最終引起衝突,只要在註冊藍圖時將不同的藍圖掛接到不同的自路徑即可
  • url_for在使用時,如果要生成一個藍圖裏面的視圖對應的路由地址,則需要聲明當前藍圖名稱+視圖名稱
url_for('users.home') # /users/home

五、註冊藍圖中的靜態文件的相關路由

和應用對象不同,藍圖對象創建時不會默認註冊靜態目錄的路由。需要我們在 創建時指定 static_folder 參數。

下面的示例將藍圖所在目錄下的static_users目錄設置爲靜態目錄

# 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')

現在就可以使用/admin/static_admin/ 訪問static_admin目錄下的靜態文件了 定製靜態目錄URL規則 :可以在創建藍圖對象時使用 static_url_path 來改變靜態目錄的路由。

下面的示例將爲 static_admin 文件夾的路由設置爲 /lib

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

六、設置藍圖中模版的目錄

藍圖對象默認的模板目錄爲系統的模版目錄,可以在創建藍圖對象時使用 template_folder 關鍵字參數設置模板目錄

創建藍圖中的模板目錄template_users :

 

admin = Blueprint('admin',__name__,template_folder='templates_users')

注:如果在 templates 中存在和 templates_users 有同名模板文件時, 則系統會優先使用 templates 中的文件

七、調整session配置

分析SQLAlachemy的構造方式可以發現,初始化並非一定要傳遞app應用對象到內部,事實上它提供了init_app方法給我們後續調用。而 init_app 方法是flask框架要求任何的第三方組件都要實現這個方法。

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

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

配置文件中:

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

    """把session保存到redis中"""
    # session存儲方式爲redis
    # SESSION_TYPE="redis"
    # # 如果設置session的生命週期是否是會話期, 爲True,則關閉瀏覽器session就失效
    # SESSION_PERMANENT = False
    # # 是否對發送到瀏覽器上session的cookie值進行加密
    # SESSION_USE_SIGNER = False
    # # 保存到redis的session數的名稱前綴
    # SESSION_KEY_PREFIX = "session:"
    # # session保存數據到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  # 如果設置爲True,則關閉瀏覽器session就失效。
    SESSION_USE_SIGNER= False  # 是否對發送到瀏覽器上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():
    """設置session"""
    session["username"] = "小明"
    return "ok"

if __name__ == '__main__':
    # db.create_all()
    print( app.url_map )
    app.run()

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章