您好,登錄后才能下訂單哦!
環境如下:
win10、Python3.6.5、Flask1.0.2
項目結構如下:
/app
/manage.py
/main
/views.py
/templates
index.html
/admin
/views.py
/templates
index.html
/app/main/views.py內容如下:
from flask import Blueprint, render_template
main = Blueprint('main', __name__, template_folder='templates')
@main.route('/')
def index():
return render_template('index.html')
/app/admin/views.py內容如下:
from flask import Blueprint, render_template
admin = Blueprint('admin', __name__, template_folder='templates', url_prefix='/admin')
@admin.route('/')
def index():
return render_template('index.html')
/app/manage.py內容如下:
from flask import Flask
from app.main import main
from app.admin import admin
def create_app():
app = Flask(__name__)
app.register_blueprint(main)
app.register_blueprint(admin)
return app
在cmd中輸入flask run(執行前記得設置FLASK_APP、FLASK_DEBUG)。待程序跑起來后,在瀏覽器
地址欄中輸入127.0.0.1:5000
,顯示的是main藍圖的inde.html。輸入127.0.0.1/admin/
,
顯示的還是 main藍圖的index.html。奇怪,這是為什么呢?浮砂在網上搜索半天,最終在flask官方的
github上找到了相關issue,感興趣的朋友可以看看。
Method render_template
does not use blueprint specified template_folder
#1361
此外,官方的文檔中也有相關說明(Templates 部分):blueprint-resources
為了方便新手朋友,浮砂翻譯成了中文,部分地方進行了補充。
Templates
模板
If you want the blueprint to expose templates you can do that by providing
the template_folder
parameter to the :class:Blueprint
constructor::
如果你想讓藍圖暴露一些模板(比如flask-bootstrap擴展提供的"bootstrap/base.html"),
可以給在構造Blueprint時,指定template_folder
參數。
admin = Blueprint('admin', __name__, template_folder='templates')
For static files, the path can be absolute or relative to the blueprint
resource folder.
對于靜態的文件,路徑可以是絕對或相對于藍圖資源文件夾的。
The template folder is added to the search path of templates but with a lower
priority than the actual application's template folder. That way you can
easily override templates that a blueprint provides in the actual application.
This also means that if you don't want a blueprint template to be accidentally
overridden, make sure that no other blueprint or actual application template
has the same relative path. When multiple blueprints provide the same relative
template path the first blueprint registered takes precedence over the others.
模板的全局搜索路徑中會自動添加這個模板文件夾,并且它的優先級低于應用的模板文件夾。這樣,
你可以在實際應用中,輕而易舉地覆蓋某個藍圖的模板。也就是說,如果不想讓某個藍圖模板
莫名其妙地被覆蓋,請確保其他的藍圖的模板相對路徑不同于實際應用的模板相對路徑。假如
多個藍圖模板被指定了相同的相對路徑,那么,當flask搜索模板的時候,先被注冊的藍圖模板
優先于后被注冊的藍圖模板。
So if you have a blueprint in the folder yourapplication/admin
and you
want to render the template 'admin/index.html'
and you have providedtemplates
as a template_folder
you will have to create a file like
this: :file:yourapplication/admin/templates/admin/index.html
. The reason
for the extra admin
folder is to avoid getting our template overridden
by a template named index.html
in the actual application template
folder.
所以說,如果你在yourapplication/admin
文件夾中編寫了一個admin藍圖,而且你還想
渲染admin/index.html
,并且你也給 template_folder
參數賦值了一個templates
,
那你就得像這樣創建你的文件yourapplication/admin/templates/admin/index.html
,
額外的那個admin
文件夾的存在,是為了不讓實際應用的模板文件夾,把我們admin
藍圖的index.html
文件覆蓋掉。
To further reiterate this: if you have a blueprint named admin
and you
want to render a template called :file:index.html
which is specific to this
blueprint, the best idea is to lay out your templates like this::
再說一遍,如果你有一個名為admin
的藍圖,并且你想渲染這個藍圖中的一個名為index.html
的模板,最好的辦法,就是把admin藍圖的模板路徑弄成像這樣:
yourpackage/
blueprints/
admin/
templates/
admin/
index.html
__init__.py
And then when you want to render the template, use :file:admin/index.html
as
the name to look up the template by. If you encounter problems loading
the correct templates enable the EXPLAIN_TEMPLATE_LOADING
config
variable which will instruct Flask to print out the steps it goes through
to locate templates on every render_template
call.
此后,每當你想渲染admin藍圖的模板,只需在調用render_template
函數時,把參數寫成admin/index.html
就行了。假如你加載模板時遇到了問題,你可以把flask提供的一個名為EXPLAIN_TEMPLATE_LOADING
的配置項設置為可用。一旦啟用了該配置,Flask就會在調用render_template
函數渲染模板時,把搜索模板的步驟全部輸出出來,非常方便。
對于文章開頭的例子,浮砂開啟了flask的EXPLAIN_TEMPLATE_LOADING
,再次訪問127.0.0.1:5000
的時候,在cmd窗口中會有如下輸出:
[2018-05-19 22:06:21,488] INFO in debughelpers: Locating template "index.html":
1: trying loader of application "flask_server.app"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- D:\app\templates
-> no match
2: trying loader of blueprint "main" (flask_server.main)
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- D:\app\main\templates
-> found ('D:\\app\\main\\templates\\index.html')
3: trying loader of blueprint "admin" (flask_server.admin)
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- D:\app\admin\templates
-> found ('D:\\app\\admin\\templates\\index.html')
Warning: multiple loaders returned a match for the template.
The template was looked up from an endpoint that belongs to the blueprint "main".
Maybe you did not place a template in the right folder?
See http://flask.pocoo.org/docs/blueprints/#templates
127.0.0.1 - - [19/May/2018 22:06:21] "GET / HTTP/1.1" 200 -
根據官方給出的建議,浮砂嘗試修改了項目的結構以及相關代碼:
更改后的項目結構如下:
/app
/manage.py
/main
/views.py
/templates
/main
/index.html
/admin
/views.py
/templates
/admin
index.html
/app/main/views.py內容如下:
from flask import Blueprint, render_template
main = Blueprint('main', __name__, template_folder='templates')
@main.route('/')
def index():
return render_template('main/index.html') # 修改后
/app/admin/views.py內容如下:
from flask import Blueprint, render_template
admin = Blueprint('admin', __name__, template_folder='templates', url_prefix='/admin')
@admin.route('/')
def index():
return render_template('admin/index.html') # 修改后
再次執行flask run(執行前記得設置FLASK_APP、FLASK_DEBUG),訪問127.0.0.1:5000
和127.0.0.1:5000/admin
,發現原來“被覆蓋”的html頁面已經能被正確地對應上了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。