Flask系列:模板

這個系列是學(xué)習(xí)《Flask Web開發(fā):基于Python的Web應(yīng)用開發(fā)實(shí)戰(zhàn)》的部分筆記

雖然可以在視圖中直接編寫 HTTP 頁面的內(nèi)容夏醉,但是這種方式很原始。將與數(shù)據(jù)庫交互的業(yè)務(wù)邏輯璃哟,與生成響應(yīng)的表現(xiàn)邏輯混在了一起。一方面不適合大型丹墨、復(fù)雜頁面的編寫望拖、維護(hù),結(jié)構(gòu)不清晰梁只,另外,由于業(yè)務(wù)邏輯通常由程序員完成埃脏,而表現(xiàn)邏輯由設(shè)計(jì)師完成搪锣,這樣雙方的工作會互相影響。

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

flask 支持 MVC 模型彩掐,由程序員在視圖中完成與數(shù)據(jù)庫的交互——業(yè)務(wù)邏輯(M)构舟,而顯示給客戶端的頁面在模板中定義(V),由設(shè)計(jì)師完成堵幽。

模板是一個包含響應(yīng)文本的文件(通常是 HTML)狗超,其中包含用 占位變量 表示的動態(tài)部分, 具體值只在收到具體的請求后弹澎,通過上下文才能知道,模板中最主要的是前端技術(shù)努咐,HTLM苦蒿、CSS、JS 等渗稍。

模板引擎實(shí)現(xiàn)對模板的渲染佩迟,就是根據(jù)上下文,對模板中的占位變量竿屹,用真實(shí)值替換报强,形成最終的響應(yīng)文件。

模板文件夾

默認(rèn)情況下,Flask 在程序文件夾中的 templates 子文件夾中尋找模板拱燃。

模板的調(diào)用

flask 使用 jinjia2 模板引擎秉溉,為了便于使用,已經(jīng)集成到 render_template 函數(shù)中碗誉,可以直接調(diào)用召嘶。

from flask import Flask, render_template

@app.route('/')
def index():
    return render_template('index.html')    # 注意,是包含 .html 后綴的完整文件名

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

第一個參數(shù)是模板的名稱诗充,然后是 鍵/值 對苍蔬,name=name左邊表示模板中的占位符,右邊是當(dāng)前視圖中的變量蝴蜓。意思是碟绑,將當(dāng)前視圖中變量name的值,賦值給模板中名為name的占位符茎匠,用于渲染格仲。

變量

  • 表示

{{ name }}

占位符,告訴模板引擎诵冒,這個位置的值從渲染模板時傳遞的數(shù)據(jù)字典中獲取

  • 支持的變量類型

支持所有類型凯肋,字符串、整型汽馋、列表侮东、字典 ......

  • 修改顯示樣式

通過使用過濾器,可以定制 變量的值 顯示的效果豹芯,比如 大小寫悄雅。{{ name | 過濾器 }}

過濾器列表

  • 模板變量

在模板中設(shè)置模板變量

{% set name = 'john' %}

控制結(jié)構(gòu)

主要用于改變渲染流程

  • 條件控制

if...else...endif

判斷條件是否符合,并執(zhí)行相應(yīng)的語句

  • 循環(huán):for...endfor

用于渲染一組元素

  • 宏:macro...endmacro

類似函數(shù)

定義一個宏铁蹈,指定宏的名稱宽闲、參數(shù),調(diào)用

{% macro x(y) %}
    ...
{% endmacro %}

{{ x(y) }}

如果需要在多個模板中復(fù)用,可以將宏的定義放入一個文件容诬,‘macro.html’

{% macro x(y) %}
    ...
{% endmacro %}

然后導(dǎo)入使用

import 'macro.html' as macro

{{ macro.x(y) }}
  • 繼承:

如果多個頁面的大部分內(nèi)容相同娩梨,可以定義一個母模板,包含相同的內(nèi)容览徒,然后子模板繼承內(nèi)容狈定,并根據(jù)需要進(jìn)行部分修改

base.html,母模板吱殉,其中掸冤,用{% block title %}...{% endblock %}定義了可以由子模板替換的區(qū)域,title是區(qū)塊的名稱友雳,可以有多個區(qū)塊

{% block title %}Hello{% endblock %}

在子模板中稿湿,聲明繼承的母模板,然后用{% block title %}...{% endblock %}指定替換哪個區(qū)塊的內(nèi)容押赊,并填入自己的內(nèi)容饺藤。子模板中沒有指定的區(qū)塊,默認(rèn)使用母模板的內(nèi)容

{% extends "base.html" %}

{% block title %}john{% endblock %}

如果希望能夠保留母版的內(nèi)容流礁,并添加新內(nèi)容涕俗,可以使用super()

{% extends "base.html" %}

{% block title %}
    {{ super() }}
    john
{% endblock %}

模板里面,不能同時有兩個{% extends " " %}語句神帅,即使另一個被注釋了也不行

  • 包含:

如果多個網(wǎng)頁中都有一段內(nèi)容相同再姑,可以將相同的內(nèi)容放入一個文件中comments.html,通過include導(dǎo)入

{% include 'comments.html' %}

bootstrap

Bootstrap是 Twitter 開發(fā)的一個開源框架,它提供的用戶界面組件可用于創(chuàng)建整潔且具有吸引力的網(wǎng)頁,而且這些網(wǎng)頁還能兼容所有現(xiàn)代 Web 瀏覽器找御。

一個名為Flask-Bootstrap的 Flask 擴(kuò)展, 可以簡化在程序中集成 Bootstrap 的過程元镀。

安裝:

$ pip install flask-bootstrap

初始化

從 flask.ext 命名空間中導(dǎo)入,然后把 程序?qū)嵗齻魅霕?gòu)造方法進(jìn)行初始化。

run.py

from flask.ext.bootstrap import Bootstrap 
# ...
bootstrap = Bootstrap(app)

初始化 Flask-Bootstrap 之后,就可以在程序中使用一個包含所有 Bootstrap 文件的基模板霎桅。 這個模板利用 Jinja2 的模板繼承機(jī)制,讓程序擴(kuò)展一個具有基本頁面結(jié)構(gòu)的基模板,其中 就有用來引入 Bootstrap 的元素栖疑。

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}
{% block navbar %}

{% endblock %}
{% block content %} <div class="container">
         <div class="page-header">
             <h1>Hello, {{ name }}!</h1>
         </div>
     </div>
{% endblock %}

Jinja2 中 的 extends 指 令 從 Flask-Bootstrap 目錄中導(dǎo)入 bootstrap/base.html, 從而實(shí)現(xiàn)模板繼承。Flask-Bootstrap 中的基模板提供了一個網(wǎng)頁框架,引入了 Bootstrap 中的所有 CSS 和 JavaScript 文件滔驶。

virtualenv 環(huán)境中遇革,目錄為lib/python2.7/site-packages/flask_bootstrap/templates/bootstrap/

基模板中定義了可在衍生模板中重定義的塊。block 和 endblock 指令定義的塊中的內(nèi)容可添加到基模板中揭糕。

Bootstrap 官方文檔是很好的學(xué)習(xí)資源,有很多可以直接復(fù)制粘貼的示例萝快。

自定義錯誤頁面

像常規(guī)路由一樣,Flask 允許程序使用基于模板的自定義錯誤頁面。最常見的錯誤代碼有兩個:404,客戶端請求未知頁面或路由時顯示;500,有未處理的異常時顯示著角。

自定義錯誤頁面

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

和視圖函數(shù)一樣,錯誤處理程序也會返回響應(yīng)杠巡。它們還返回與該錯誤對應(yīng)的數(shù)字狀態(tài)碼。 返回指定的數(shù)字狀態(tài)碼似乎沒有什么用 雇寇?

url_for 生成連接

模板中可能有去往多個不同頁面的鏈接,例如導(dǎo)航條。

在模板中直接編寫簡單路由的 URL 鏈接不難,但對于包含可變部分的動態(tài)路由,在模板中構(gòu)建正確的 URL 就很困難。而且,直接編寫 URL 會對代碼中定義的路由產(chǎn)生不必要的 依賴關(guān)系(hardcode)锨侯。如果修改 路由嫩海、視圖 的綁定關(guān)系, 模板中的鏈接可能會失效。

為了避免這些問題,Flask 提供了url_for()輔助函數(shù),它可以使用程序URL映射中保存的信息,根據(jù)視圖名稱生成 URL囚痴。

例如叁怪,對于下面的視圖

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

調(diào)用 url_ for('index')得到的結(jié)果是/。調(diào)用url_for('index', _external=True)返回的則是絕對地址,是http://localhost:5000/深滚。

在程序內(nèi)(模板奕谭、視圖中)生成連接程序內(nèi)不同路由的鏈接時,使用相對地址就足夠了,瀏覽器痴荐、程序能夠根據(jù)當(dāng)前的 URL 補(bǔ)全血柳。但如果要在瀏覽器以外生成鏈接,例如在確認(rèn)郵件中的鏈接,則必須使用絕對地址,否則誰也不知道前綴是什么生兆。

使用url_for()生成鏈接時,將動態(tài)部分作為關(guān)鍵字參數(shù)傳入难捌。例如,

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

url_for ('user', name='john', _external=True) 的返回結(jié)果是 http://localhost:5000/user/john

默認(rèn) _external 為 False鸦难,表示生成相對路徑根吁;為 True 時,表示生成絕對路徑

函數(shù)能將任何額外參數(shù)添加到查詢字符串中合蔽。例如,

url_for('user', name='john', page=2)的返回結(jié)果是/user/john/?page=2

對于多層的模板結(jié)構(gòu)击敌,render_template 函數(shù)中需要添加從templates目錄下文件夾開始的路徑信息,render_template('main/index.html')拴事,結(jié)構(gòu)為templates/main/index.html沃斤,url_for() 需要用.隔開目錄,url_for('main.index.html')挤聘。

Jinja2

更多jinja2 模板的語法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轰枝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子组去,更是在濱河造成了極大的恐慌鞍陨,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件从隆,死亡現(xiàn)場離奇詭異诚撵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)键闺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門寿烟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辛燥,你說我怎么就攤上這事筛武》炱洌” “怎么了?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵徘六,是天一觀的道長内边。 經(jīng)常有香客問我,道長待锈,這世上最難降的妖魔是什么漠其? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮竿音,結(jié)果婚禮上和屎,老公的妹妹穿的比我還像新娘。我一直安慰自己春瞬,他們只是感情好柴信,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著快鱼,像睡著了一般颠印。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抹竹,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天线罕,我揣著相機(jī)與錄音,去河邊找鬼窃判。 笑死钞楼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的袄琳。 我是一名探鬼主播询件,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唆樊!你這毒婦竟也來了宛琅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤逗旁,失蹤者是張志新(化名)和其女友劉穎嘿辟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體片效,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡红伦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了淀衣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昙读。...
    茶點(diǎn)故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖膨桥,靈堂內(nèi)的尸體忽然破棺而出蛮浑,到底是詐尸還是另有隱情唠叛,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布沮稚,位于F島的核電站玻墅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏壮虫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一环础、第九天 我趴在偏房一處隱蔽的房頂上張望囚似。 院中可真熱鬧,春花似錦线得、人聲如沸饶唤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽募狂。三九已至,卻和暖如春角雷,著一層夾襖步出監(jiān)牢的瞬間祸穷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工勺三, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雷滚,地道東北人。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓吗坚,卻偏偏與公主長得像祈远,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子商源,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評論 2 361

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

  • 22年12月更新:個人網(wǎng)站關(guān)停车份,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,191評論 22 257
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)牡彻,斷路器扫沼,智...
    卡卡羅2017閱讀 134,719評論 18 139
  • 第三章 模板 序 為什么要分離 易于維護(hù)的代碼,關(guān)鍵在于保持簡單的結(jié)構(gòu)讨便。而我們之前編寫的hello.py雖然簡單充甚,...
    科幻經(jīng)典閱讀 1,537評論 0 6
  • 第三章 模板(Templates) 編寫易于維護(hù)的程序的要點(diǎn)在于書寫干凈、良好結(jié)構(gòu)的代碼霸褒。你以前所見的代碼都過于...
    易木成華閱讀 1,142評論 0 2
  • 渲染模板 模板文件后綴名是 .html伴找, 這些文件就是普通的 html 文件加上一些占位符變量, 它們都默認(rèn)存放在...
    焉知非魚閱讀 693評論 0 1