溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

flask的html模板的覆蓋問題

發(fā)布時間:2020-07-24 19:21:42 來源:網(wǎng)絡(luò) 閱讀:1061 作者:fushall 欄目:開發(fā)技術(shù)

環(huán)境如下:
win10、Python3.6.5、Flask1.0.2

項目結(jié)構(gòu)如下:

/app
    /manage.py
    /main
        /views.py
        /templates
            index.html    
    /admin
        /views.py
        /templates 
            index.html   

/app/main/views.py內(nèi)容如下:

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內(nèi)容如下:

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內(nèi)容如下:

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(執(zhí)行前記得設(shè)置FLASK_APP、FLASK_DEBUG)。待程序跑起來后,在瀏覽器
地址欄中輸入127.0.0.1:5000,顯示的是main藍圖的inde.html。輸入127.0.0.1/admin/,
顯示的還是 main藍圖的index.html。奇怪,這是為什么呢?浮砂在網(wǎng)上搜索半天,最終在flask官方的
github上找到了相關(guān)issue,感興趣的朋友可以看看。
Method render_template does not use blueprint specified template_folder #1361

此外,官方的文檔中也有相關(guān)說明(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"),
可以給在構(gòu)造Blueprint時,指定template_folder參數(shù)。

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

For static files, the path can be absolute or relative to the blueprint
resource folder.

對于靜態(tài)的文件,路徑可以是絕對或相對于藍圖資源文件夾的。

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.

模板的全局搜索路徑中會自動添加這個模板文件夾,并且它的優(yōu)先級低于應(yīng)用的模板文件夾。這樣,
你可以在實際應(yīng)用中,輕而易舉地覆蓋某個藍圖的模板。也就是說,如果不想讓某個藍圖模板
莫名其妙地被覆蓋,請確保其他的藍圖的模板相對路徑不同于實際應(yīng)用的模板相對路徑。假如
多個藍圖模板被指定了相同的相對路徑,那么,當flask搜索模板的時候,先被注冊的藍圖模板
優(yōu)先于后被注冊的藍圖模板。

So if you have a blueprint in the folder yourapplication/admin and you
want to render the template 'admin/index.html' and you have provided
templates 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參數(shù)賦值了一個templates,
那你就得像這樣創(chuàng)建你的文件yourapplication/admin/templates/admin/index.html,
額外的那個admin文件夾的存在,是為了不讓實際應(yīng)用的模板文件夾,把我們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藍圖的模板,只需在調(diào)用render_template函數(shù)時,把參數(shù)寫成
admin/index.html就行了。假如你加載模板時遇到了問題,你可以把flask提供的一個名為
EXPLAIN_TEMPLATE_LOADING的配置項設(shè)置為可用。一旦啟用了該配置,F(xiàn)lask就會在調(diào)用
render_template函數(shù)渲染模板時,把搜索模板的步驟全部輸出出來,非常方便。

對于文章開頭的例子,浮砂開啟了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 -

根據(jù)官方給出的建議,浮砂嘗試修改了項目的結(jié)構(gòu)以及相關(guān)代碼:

更改后的項目結(jié)構(gòu)如下:
/app
    /manage.py
    /main
        /views.py
        /templates
            /main
                /index.html    
    /admin
        /views.py
        /templates
            /admin 
                index.html   

/app/main/views.py內(nèi)容如下:

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內(nèi)容如下:

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')  # 修改后

再次執(zhí)行flask run(執(zhí)行前記得設(shè)置FLASK_APP、FLASK_DEBUG),訪問127.0.0.1:5000
127.0.0.1:5000/admin,發(fā)現(xiàn)原來“被覆蓋”的html頁面已經(jīng)能被正確地對應(yīng)上了。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI