一.Flask模板中的特殊變量和函數(shù)
用途:可以在自己的模板中訪問一些Flask默認(rèn)內(nèi)置的函數(shù)和對(duì)象.當(dāng)然灸姊,這些變量在視圖中也可以使用.
1.config
可以從模板中直接訪問Flask當(dāng)前的config的對(duì)象:
{{ config.DEBUG}}?
{{config.SECRET_KEY}}
可以寫成列表形式或者:
{{[config.DEBUG, config.SECRET_KEY]}} --> 結(jié)果是列表
或者 {{ config.DEBUG, config.SECRET_KEY}}
2.request
即Flask中代表當(dāng)前請(qǐng)求的request對(duì)象
{{request.url}} ?--> http://127.0.0.1:5000/
3.session
即Flask的session對(duì)象
{{session.username}} --> qia
4.g變量
在視圖中設(shè)置g變量的 name 屬性的值黍析,然后在模板中直接可以取出.
{{g.name}}
5.url_for
? ? url_for會(huì)根據(jù)傳入的路由器函數(shù)名,返回該路由對(duì)應(yīng)的URL,在模板中始終使用url_for()就可以安全的修改路由綁定的URL,則不必須擔(dān)心模板中渲染出錯(cuò)的鏈接:
{{url_for('index'}}} --> /qi
? ? 如果我們定義的路由URL是帶有參數(shù)的,則可以把它們作為關(guān)鍵字參數(shù)傳入url_for(),Flask會(huì)把他們填充進(jìn)最終生成的URL中:
{{ url_for('post', post_id=1)}} ?-->/post/1
6.get_flashed_messages()
? ? ? ?這個(gè)函數(shù)會(huì)返回之前在flask中通過flask()傳入的消息的列表光绕,flash函數(shù)的作用很簡(jiǎn)單,可以把由Python字符串表示的消息加入一個(gè)消息隊(duì)列中健无,再使用get_flashed_message()函數(shù)取出它們并消費(fèi)掉:
{%for message in get_flashed_messages()%}
? ? {{message}}
{%endfor%}
二.模板代碼的復(fù)用
Flask中模板代碼的復(fù)用有 3 種方式:
宏: 多個(gè)模板具有完全相同的頂部和底部?jī)?nèi)容谱邪。
繼承:多個(gè)模板中具有相同的模板代碼內(nèi)容蒲拉,但是內(nèi)容中部分值不一樣慌随。
包括:(多個(gè))模板中具有完全相同的 html 代碼塊內(nèi)容。
1.宏
對(duì)宏(macro)的理解:
? ? 把它看作 Jinja2 中的一個(gè)函數(shù)焰坪,它會(huì)返回一個(gè)模板或者 HTML 字符串.
? ? 為了避免反復(fù)地編寫同樣的模板代碼趣倾,出現(xiàn)代碼冗余,可以把他們寫成函數(shù)以進(jìn)行重用.
? ? 需要在多處重復(fù)使用的模板代碼片段可以寫入單獨(dú)的文件某饰,再包含在所有模板中儒恋,以避免重復(fù).
使用:包括 定義 和 調(diào)用 2 個(gè)步驟.
<1>定義宏
定義語法:{% macro 函數(shù)名(參數(shù))%}
? ? ? ? ? ? ? ?復(fù)用代碼塊
? ? ? ? ? {% endmacro %}
使用:
{% macro input(name,value='',type='text') %}
? ? <input type="{{type}}" name="{{name}}"
? ? ? ? value="{{value}}" class="form-control">
{% endmacro %}
<2>調(diào)用宏
調(diào)用語法:{ % import '宏文件所在文件名' as 別名}
? ? ? ? ? {{ 別名.調(diào)用宏的函數(shù)名(參數(shù))}}
{{ input('name' value='zs')}}
這會(huì)輸出
<input type="text" name="name"
? ? value="zs" class="form-control">
主要用途:
把宏單獨(dú)抽取出來,封裝成html文件黔漂,其它模板中導(dǎo)入使用诫尽,文件名可以自定義macro.html
{% macro function(type='text', name='', value='') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" class="form-control">
{% endmacro %}
在其它模板文件中先導(dǎo)入,再調(diào)用
{% import 'macro.html' as func %}
{% func.function() %}
2.模板繼承
? ? ? ?模板繼承是為了重用模板中的公共內(nèi)容炬守。一般Web開發(fā)中牧嫉,繼承主要使用在網(wǎng)站的頂部菜單、底部减途。這些內(nèi)容可以定義在父模板中酣藻,子模板直接繼承,而不需要重復(fù)書寫鳍置。
標(biāo)簽定義的內(nèi)容
{% block top %} {% endblock %}
相當(dāng)于在父模板中挖個(gè)坑辽剧,當(dāng)子模板繼承父模板時(shí),可以進(jìn)行填充税产。
子模板使用 extends 指令聲明這個(gè)模板繼承自哪個(gè)模板
父模板中定義的塊在子模板中被重新定義抖仅,在子模板中調(diào)用父模板的內(nèi)容可以使用super()
父模板
base.html
{% block top %}
? 頂部菜單
{% endblock top %}
{% block content %}
{% endblock content %}
{% block bottom %}
? 底部
{% endblock bottom %}
子模板
extends指令聲明這個(gè)模板繼承自哪
{% extends 'base.html' %}
{% block content %}
?需要填充的內(nèi)容
{% endblock content %}
模板繼承使用時(shí)注意點(diǎn):
<1>不支持多繼承
<2>為了便于閱讀,在子模板中使用extends時(shí)砖第,盡量寫在模板的第一行撤卢。
<3>不能在一個(gè)模板文件中定義多個(gè)相同名字的block標(biāo)簽。
<4>當(dāng)在頁面中使用多個(gè)block標(biāo)簽時(shí)梧兼,建議給結(jié)束標(biāo)簽起個(gè)名字放吩,當(dāng)多個(gè)block嵌套時(shí),閱讀性更好羽杰。
父模板和子模板的特點(diǎn)和功能:
父模板:抽取多個(gè)模板頁面中的相同部分,一般包括頂部/中間/底部?jī)?nèi)容
子模板:繼承父模板,可以完全服用父模板內(nèi)容,也可以在父模板的基礎(chǔ)上實(shí)現(xiàn)自己特有的頁面內(nèi)容.
<1>如果想要實(shí)現(xiàn)自己特有的頁面內(nèi)容,重寫指定區(qū)域塊,自己填充內(nèi)容;
<2>如果不想要父模板中的部分內(nèi)容,直接聲明區(qū)域塊,內(nèi)容為空.
<3>如果既要實(shí)現(xiàn)自己的特有內(nèi)容,又想使用父模板的,使用super().
<4>可以使用多繼承,但是不建議使用.
3.包含
? ? ? ?Jinja2模板中渡紫,除了宏和繼承到推,還支持一種代碼重用的功能,叫包含(Include)惕澎。它的功能是將另一個(gè)模板整個(gè)加載到當(dāng)前模板中莉测,并直接渲染。
本質(zhì):代碼完全復(fù)用.
include的使用
{% include 'hello.html' %}
包含在使用時(shí)唧喉,如果包含的模板文件不存在時(shí)捣卤,程序會(huì)拋出TemplateNotFound異常,可以加上 ignore missing 關(guān)鍵字八孝。如果包含的模板文件不存在董朝,會(huì)忽略這條include語句。
include 的使用加上關(guān)鍵字ignore missing
{% include 'hello.html' ignore missing %}
三.控制代碼塊
? ? ? ? 控制代碼塊主要包含兩個(gè):
- if/else if /else / endif
- for / endfor
1. if語句
Jinja2 語法中的if語句跟 Python 中的 if 語句相似,后面的布爾值或返回布爾值的表達(dá)式將決定代碼中的哪個(gè)流程會(huì)被執(zhí)行:
{%if user.is_logged_in() %}
? ? <a href='/logout'>Logout</a>
{% else %}
? ? <a href='/login'>Login</a>
{% endif %}
過濾器可以被用在 if 語句中:
{% if comments | length > 0 %}
? ? There are {{ comments | length }} comments
{% else %}
? ? There are no comments
{% endif %}
2. 循環(huán)
我們可以在 Jinja2 中使用循環(huán)來迭代任何列表或者生成器函數(shù)
{% for post in posts %}
? ? <div>
? ? ? ? <h1>{{ post.title }}</h1>
? ? ? ? <p>{{ post.text | safe }}</p>
? ? </div>
{% endfor %}
循環(huán)和if語句可以組合使用干跛,以模擬 Python 循環(huán)中的 continue 功能子姜,下面這個(gè)循環(huán)將只會(huì)渲染post.text不為None的那些post:
{% for post in posts if post.text %}
? ? <div>
? ? ? ? <h1>{{ post.title }}</h1>
? ? ? ? <p>{{ post.text | safe }}</p>
? ? </div>
{% endfor %}
在一個(gè) for 循環(huán)塊中你可以訪問這些特殊的變量:
變量?? ?描述
loop.index?? ?當(dāng)前循環(huán)迭代的次數(shù)(從 1 開始)
loop.index0?? ?當(dāng)前循環(huán)迭代的次數(shù)(從 0 開始)
loop.revindex?? ?到循環(huán)結(jié)束需要迭代的次數(shù)(從 1 開始)
loop.revindex0?? ?到循環(huán)結(jié)束需要迭代的次數(shù)(從 0 開始)
loop.first?? ?如果是第一次迭代,為 True 楼入。
loop.last?? ?如果是最后一次迭代哥捕,為 True 。
loop.length?? ?序列中的項(xiàng)目數(shù)嘉熊。
loop.cycle?? ?在一串序列間期取值的輔助函數(shù)遥赚。見下面示例程序。
在循環(huán)內(nèi)部,你可以使用一個(gè)叫做loop的特殊變量來獲得關(guān)于for循環(huán)的一些信息
比如:要是我們想知道當(dāng)前被迭代的元素序號(hào)记舆,并模擬Python中的enumerate函數(shù)做的事情,則可以使用loop變量的index屬性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}
會(huì)輸出這樣的結(jié)果
1, Post title
2, Second Post
cycle函數(shù)會(huì)在每次循環(huán)的時(shí)候,返回其參數(shù)中的下一個(gè)元素,可以拿上面的例子來說明:
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}
會(huì)輸出這樣的結(jié)果:
odd Post Title
even Second Post