1.1 藍圖的基本使用
在我的flask中,我們可以利用藍圖對程序目錄的划分。
思考如果我們有很多個視圖函數,比如下面這樣我們是不是應該抽取出來專門的py文件進行管理呢?
from flask import Flask
app = Flask(__name__)
@app.route('/login/')
def login():
return "login"
@app.route('/logout/')
def logout():
return "logout"
@app.route('/add_order/')
def add_order():
return "add_order"
@app.route('modify_order')
def modify_order():
return "modify_order"
if __name__ == '__main__':
app.run()
上面的這種是不是會顯得主運行文件特別亂,這個時候我們的藍圖就閃亮登場了。
1.1.1實例:
項目目錄:
-templates
-static
-views
-user.py
-order.py
-app.py
views/user.py
from flask import Blueprint
# 1 創建藍圖
user_bp = Blueprint('user',__name__)
# 2 利用藍圖創建路由關系
@user_bp.route('/login/')
def login():
return "login"
@user_bp.route('/logout/')
def logout():
return "logout"
views/order.py
from flask import Blueprint
order_bp = Blueprint('order',__name__)
@order_bp.route('/add_order/')
def add_order():
return "add_order"
@order_bp.route('/modify_order/')
def modify_order():
return "modify_order"
app.py
from flask import Flask
from views.user import user_bp
from views.order import order_bp
app = Flask(__name__)
# 3 注冊藍圖
app.register_blueprint(user_bp)
app.register_blueprint(order_bp)
if __name__ == '__main__':
app.run()
訪問:
其他的幾條路由也是直接訪問,在此就不做展示了。
講解:
觀察views/user.py
-
我們可以把所有的視圖函數抽出來多個文件。
-
在這里我們通過
user_bp = Blueprint('user',__name__)
創建一個藍圖對象參數講解:
- user_bp :是用於指向創建出的藍圖對象,可以自由命名。
- Blueprint的第一個參數自定義命名的
‘user’
用於url_for
翻轉url
時使用。 __name__
用於尋找藍圖自定義的模板和靜態文件使用。
-
藍圖對象的用法和之前實例化出來的app對象用法很像,可以進行注冊路由。
觀察app.py
- 這里我們需要手動的去注冊一下藍圖,才會建立上url和視圖函數的映射關系。
關鍵詞:
-
創建藍圖
user_bp = Blueprint('user',__name__)
-
利用藍圖創建路由關系
@bp.route('/login/') def login(): return "login"
-
注冊藍圖 app.register_blueprint(bp)
3.2 藍圖的高級使用(重點備課內容)
3.2.1 藍圖中實現path部分的url前綴
創建藍圖的時候填寫url_prefix
可以為增加url的path部分的前綴,可以更方便的去管理訪問視圖函數。
from flask import Blueprint
# 1 創建藍圖
user_bp = Blueprint('user',__name__,url_prefix='/user')
# 注意斜杠跟視圖函數的url連起來時候不要重復了。
注意:
2.url加前綴的時候也可以再注冊藍圖的時候加上,更推薦這么做,因為代碼的可讀性更強。
Copyapp.register_blueprint(user_bp,url_prefix='/order')
3.3.2 藍圖中自定義模板路徑
創建藍圖的時候填寫template_folder
可以指定自定義模板路徑
# 1 創建藍圖 #所對應的參數路徑是相對於藍圖文件的
user_bp = Blueprint('user',__name__,url_prefix='/user',template_folder='views_templates')
注意:
-
藍圖雖然指定了自定義的模板查找路徑,但是查找順序還是會先找主app規定的模板路徑(templates),找不到再找藍圖自定義的模板路徑。
-
Blueprint
的template_folder
參數指定的自定義模板路徑是相對於藍圖文件的路徑。圖解:
(01)
(02)
3.3.3 藍圖中自定義靜態文件路徑
創建藍圖的時候填寫static_folder
可以指定自定義靜態文件的路徑
user_bp = Blueprint('user',__name__,url_prefix='/user',template_folder='views_templates',
static_folder='views_static')
注意:
- 在模板中使用自定義的靜態文件路徑需要依賴
url_for()
- 下節講解如何在模板中應用藍圖自定義的靜態文件。
3.3.4 url_for()翻轉藍圖
視圖中翻轉url:
url_for('創建藍圖時第一個參數.藍圖下的函數名')
# 如:
url_for('user.login')
模板中翻轉url:
{{ url_for('創建藍圖時第一個參數.藍圖下的函數名') }}
# 如:
{{ url_for('user.login') }}
模板中應用藍圖自定義路徑的靜態文件:
{{ url_for('創建藍圖時第一個參數.static',filename='藍圖自定義靜態文件路徑下的文件') }}
# 如:
{{ url_for('user.static',filename='login.css') }}
3.3.5 藍圖子域名的實現
創建藍圖的時候填寫subdomain
可以指定子域名,可以參考之前注冊路由中實現子域名。
(1) 配置C:\Windows\System32\drivers\etc\hosts
127.0.0.1 bookmanage.com
127.0.0.1 admin.bookmanage.com
(2)給app增加配置
app.config['SERVER_NAME'] = 'bookmanage.com:5000'
(3)創建藍圖的時候添加子域名 subdomain='admin'
# 1 創建藍圖
user_bp = Blueprint('user',__name__,url_prefix='/user',template_folder='views_templates',
static_folder='views_static',subdomain='admin')
# 2 利用藍圖創建路由關系
@user_bp.route('/login/')
def login():
return render_template('login_master.html')
(4) 訪問admin.bookmanage.com:5000/user/login/
3.3.6 藍圖中使用自己請求擴展
在藍圖中我們可以利用創建好的藍圖對象,設置訪問藍圖的視圖函數的時候觸發藍圖獨有的請求擴展。
例如:
order_bp = Blueprint('order',__name__)
@order_bp.route('/add_order/')
def add_order():
return "add_order"
@order_bp.before_request
def order_bp_before_request():
return '請登錄'
注意:
- 只有訪問該藍圖下的視圖函數時候才會觸發該藍圖的請求擴展。
- 可以這么理解:相當app的請求擴展是全局的,而藍圖的請求擴展是局部的只對本藍圖下的視圖函數有效。
3.3 使用藍圖之中小型系統
目錄結構:
-flask_small_pro
-app01
-__init__.py
-static
-templates
-views
-order.py
-user.py
-manage.py
__init__.py
from flask import Flask
from app01.views.user import user_bp
from app01.views.order import order_bp
app = Flask(__name__)
app.register_blueprint(user_bp,url_prefix='/user')
app.register_blueprint(order_bp)
user.py
from flask import Blueprint
user_bp = Blueprint('user',__name__)
@user_bp.route('/login/')
def login():
return 'login'
@user_bp.route('/logout/')
def logout():
return 'logout'
order.py
from flask import Blueprint
order_bp = Blueprint('order',__name__)
@order_bp.route('/add_order/')
def add_order():
return 'buy_order'
@order_bp.route('/modify_order/')
def modify_order():
return 'modify_order'
manage.py
from app01 import app
if __name__ == '__main__':
app.run()
3.4 使用藍圖之使用大型系統
這里所謂的大型系統並不是絕對的大型系統,而是相對規整的大型系統,相當於提供了一個參考,在真實的生成環境中會根據公司的項目以及需求,規划自己的目錄結構。
文件路徑:
│ run.py
│
│
└─pro_flask # 文件夾
│ __init__.py
│
├─admin # 文件夾
│ │ views.py
│ │ __init__.py
│ │
│ ├─static # 文件夾
│ └─templates # 文件夾
│
└─web # 文件夾
│ views.py
│ __init__.py
│
├─static # 文件夾
└─templates # 文件夾
run.py 啟動app
from pro_flask import app
if __name__ == '__main__':
app.run()
__init__.py
實例化核心類,導入藍圖對象,注冊藍圖。
from flask import Flask
from .admin import admin
from .web import web
app = Flask(__name__)
app.debug = True
app.register_blueprint(admin, url_prefix='/admin')
app.register_blueprint(web)
admin.views.py 完成注冊路由以及視圖函數
from . import admin
@admin.route('/index')
def index():
return 'Admin.Index'
admin.__init__.py
生成藍圖對象導入views,使得views的代碼運行完成注冊路由
from flask import Blueprint
admin = Blueprint(
'admin',
__name__,
template_folder='templates',
static_folder='static'
)
from . import views
web文件夾下和admin文件夾下目錄構成完全一致,這里就不舉例子了
2. 多app的使用(有了藍圖基本不用這個)
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from flask import Flask, current_app
app1 = Flask('app01')
app2 = Flask('app02')
@app1.route('/index')
def index():
return "app01"
@app2.route('/index2')
def index2():
return "app2"
# http://www.oldboyedu.com/index
# http://www.oldboyedu.com/sec/index2
dm = DispatcherMiddleware(app1, {
'/sec': app2,
})
if __name__ == "__main__":
run_simple('localhost', 5000, dm)