使用 Blueprint 要注意 render_template 函數(shù)

此文章主要是為了記錄在使用 Flask 的過程中遇到的問題王浴。本章主要討論 render_template 函數(shù)的問題柔吼。

使用 Flask 的同學都應該知道,項目中的 url 和視圖函數(shù)是在字典里一一對應著的,再詳細一點,就是 url 對應著 endpoint肩民,視圖函數(shù)也對應著 endpoint,并且 endpoint 在字典里是唯一存在的撬槽。

而對于不同 Blueprint 里的 url,是依靠所注冊的藍圖以及不同的前綴來進行區(qū)分趾撵。但是在視圖函數(shù)中所調(diào)用的 render_template 函數(shù)可得不到 endpoint 的支持侄柔,如果你使用的不同目錄下的一樣命名的模板文件,那么就會出現(xiàn)問題了占调。

先擺事實暂题、再講道理。

明了問題所在

實例項目的目錄結(jié)構(gòu)如下:

app
├── admin
│   ├── errors.py
│   ├── forms.py
│   ├── __init__.py
│   ├── static
│   │   ├── css
│   ├── templates
│   │   ├── index.html
│   ├── views.py
├── __init__.py
├── main
│   ├── errors.py
│   ├── forms.py
│   ├── __init__.py
│   ├── templates
│   │   └── ousi
│   │       ├── index.html
│   │       ├── static
│   │       │   ├── css
│   ├── views.py
├── models.py

該項目中注冊兩個 Blueprint究珊,即 admin 是所謂的后臺管理藍圖薪者,main 是所謂的前臺展示藍圖。
藍圖 admin 的 __init__.py 內(nèi)容如下:

# -*- coding:utf-8 -*-
__author__ = '東方鶚'


from flask import Blueprint

admin = Blueprint('admin', __name__, template_folder="templates", static_folder='static')

# 在末尾導入相關(guān)模塊剿涮,是為了避免循環(huán)導入依賴言津,因為在下面的模塊中還要導入藍本main
from . import views, errors

藍圖 main 的 __init__.py 內(nèi)容如下:

# -*- coding:utf-8 -*-
__author__ = '東方鶚'


from flask import Blueprint


main = Blueprint('main', __name__, template_folder="templates/ousi",
                                 static_folder='templates/ousi/static')

# 在末尾導入相關(guān)模塊攻人,是為了避免循環(huán)導入依賴,因為在下面的模塊中還要導入藍本main
from . import views, errors

在定義兩個藍圖的時候悬槽,也對本藍圖所對應的模板文件夾和靜態(tài)文件夾進行了定義怀吻,此文主要關(guān)注模板文件夾

那么初婆,現(xiàn)在就說說出現(xiàn)了什么問題蓬坡。

在各自藍圖的視圖函數(shù)中都對主頁 '/' 或叫做 'index' 進行了定義。

其中磅叛,藍圖 admin 的視圖函數(shù)定義如下:

@admin.route('/', methods=['GET', 'POST'])
@login_required
def index():

    return render_template('index.html')

請記住最后的代碼屑咳,即 render_template('index.html'),此處調(diào)用的模板名叫做 index.html弊琴。

藍圖 admin 的視圖函數(shù)定義如下:

@main.route('/', methods=['GET', 'POST'])
def index():

    return render_template('index.html')

請記住最后的代碼兆龙,即 render_template('index.html'),此處調(diào)用的模板名叫做 index.html访雪。

到此详瑞,你發(fā)現(xiàn)了什么,你發(fā)現(xiàn)了什么臣缀,我估計你已經(jīng)看出來兩個視圖函數(shù)的最后一行代碼是一樣的坝橡,說得再精確點,調(diào)用的模板名是一樣的精置。但是此處我們要保持清醒计寇,雖然模板名稱一樣,但是所在目錄是不一樣的脂倦,它們所處的位置是各自所在的藍圖所定義的模板文件夾里番宁。

說了這么多,到底怎么了呢赖阻。

這時蝶押,如果你測試一下你的程序的話,你會發(fā)現(xiàn)兩個藍圖所顯示的內(nèi)容是一樣的火欧,不管你相信不相信自己的眼睛棋电,它就是一樣的界面,而且絕對一樣苇侵,因為 render_template('index.html') 調(diào)用的是同一個模板赶盔,它可不會區(qū)分藍圖。

那么榆浓,到底調(diào)用的是那個藍圖下的模板呢于未??繼續(xù)往下看。

這時你打開 app/__init__.py烘浦,內(nèi)容如下:


def create_app(config_name):
    """ 使用工廠函數(shù)初始化程序?qū)嵗?""
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app=app)

    # mail.init_app(app=app)
    moment.init_app(app=app)
    db.init_app(app=app)
    md.init_app(app=app)
    login_manager.init_app(app=app)

    # 注冊藍本 main
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint, url_prefix='/main')

    # 注冊藍本 admin
    from .admin import admin as admin_blueprint
    app.register_blueprint(admin_blueprint, url_prefix='/admin')

    # 注冊藍本 main
    #from .main import main as main_blueprint
    #app.register_blueprint(main_blueprint, url_prefix='/dynamic')

    return app

到底調(diào)用的是那個藍圖下的模板呢抖坪??

這個谎倔,我可以明確告訴你柳击,main 和 admin 兩個藍圖,哪個在 app/__init__.py 中先注冊片习,就調(diào)用那個藍圖的模板捌肴,也就是說哪個藍圖注冊時所用的代碼寫得靠上,就調(diào)用那個藍圖的模板藕咏。

這到底是為什么呢状知?為什么呢?這是 flask 項目的一個小 bug孽查。寫項目的時候饥悴,要注意此坑,render_template() 函數(shù)里所調(diào)用的模板一定要保證命名在整個項目中的唯一性盲再。

號外西设,號外

今天又發(fā)現(xiàn)了一個坑,就是 jinja2 內(nèi)部的模板調(diào)用答朋,比如 include 某某模板的時候贷揽,這個被調(diào)用的模板名稱也需要,而且強烈需要保證在整個項目梦碗,記住是整個項目中禽绪,其命名要具有唯一性。

查看原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洪规,一起剝皮案震驚了整個濱河市印屁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斩例,老刑警劉巖雄人,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異念赶,居然都是意外死亡础钠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門晶乔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來珍坊,“玉大人牺勾,你說我怎么就攤上這事正罢。” “怎么了驻民?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵翻具,是天一觀的道長履怯。 經(jīng)常有香客問我,道長裆泳,這世上最難降的妖魔是什么叹洲? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮工禾,結(jié)果婚禮上运提,老公的妹妹穿的比我還像新娘。我一直安慰自己闻葵,他們只是感情好民泵,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著槽畔,像睡著了一般栈妆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厢钧,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天鳞尔,我揣著相機與錄音,去河邊找鬼早直。 笑死寥假,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的莽鸿。 我是一名探鬼主播昧旨,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祥得!你這毒婦竟也來了兔沃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤级及,失蹤者是張志新(化名)和其女友劉穎乒疏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饮焦,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡怕吴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了县踢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片转绷。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖硼啤,靈堂內(nèi)的尸體忽然破棺而出议经,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布煞肾,位于F島的核電站咧织,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏籍救。R本人自食惡果不足惜习绢,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蝙昙。 院中可真熱鬧闪萄,春花似錦、人聲如沸奇颠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽大刊。三九已至为迈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缺菌,已是汗流浹背葫辐。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工筝闹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聂示,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓落包,卻偏偏與公主長得像焊傅,于是被迫代替她去往敵國和親剂陡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個人網(wǎng)站關(guān)停狐胎,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,170評論 22 257
  • 解釋1: 允許將應用組織為模塊鸭栖,每個模塊有自洽的 MVC,開發(fā)者做些工作可以使模塊間依賴盡可能少握巢,必要時可以按 b...
    大詩兄_zl閱讀 2,202評論 1 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理晕鹊,服務發(fā)現(xiàn),斷路器暴浦,智...
    卡卡羅2017閱讀 134,639評論 18 139
  • 全文鏈接 第一章 創(chuàng)建一個blog應用第二章 使用高級特性來增強你的blog第三章 擴展你的blog應用第四章上 ...
    夜夜月閱讀 8,827評論 27 31
  • (一)歌焦、啟動服務器 (二)飞几、創(chuàng)建數(shù)據(jù)庫表 或 更改數(shù)據(jù)庫表或字段 Django 1.7.1及以上 用以下命令 1....
    夏天夏星閱讀 5,637評論 0 17