摘要:用真實(shí)的值替換變量并返回最終響應(yīng)字符串,這個(gè)過程稱為渲染。示例展示模板實(shí)現(xiàn)該響應(yīng)??刂平Y(jié)構(gòu)提供一些控制結(jié)構(gòu)用于改變模板流。這個(gè)示例展示如何使用循環(huán)做到這些同樣支持宏,這和代碼中的函數(shù)很像。
寫代碼最關(guān)鍵的是要易于維護(hù)且結(jié)構(gòu)清晰整潔。目前為止,你看到的例子都過于簡(jiǎn)單從而沒有做這方面的要求。Flask視圖函數(shù)希望將兩個(gè)應(yīng)該完全獨(dú)立的任務(wù)一并處理,兩個(gè)任務(wù)有兩種代碼,一并處理勢(shì)必會(huì)引發(fā)問題。
明擺著的任務(wù)就是生成響應(yīng),就像你在第二章看到的示例那樣。對(duì)于最簡(jiǎn)單的請(qǐng)求確實(shí)已經(jīng)足夠,但是一般而言一個(gè)請(qǐng)求會(huì)觸發(fā)應(yīng)用程序的狀態(tài)發(fā)生改變,而視圖函數(shù)就是產(chǎn)生這個(gè)改變的地方。
例如,用戶在網(wǎng)站上注冊(cè)一個(gè)新的賬戶。用戶輸入郵箱地址和密碼到表單并點(diǎn)擊提交按鈕。一個(gè)包含數(shù)據(jù)的請(qǐng)求從用戶到服務(wù)器,F(xiàn)lask將其派發(fā)給視圖函數(shù)去處理這個(gè)注冊(cè)請(qǐng)求。這個(gè)視圖函數(shù)需要告訴數(shù)據(jù)庫(kù)添加新的用戶并生成一個(gè)響應(yīng)發(fā)回給瀏覽器。這兩類任務(wù)通常被稱作業(yè)務(wù)邏輯和 顯示邏輯。
混合業(yè)務(wù)邏輯和顯示邏輯會(huì)導(dǎo)致代碼非常的難以理解和維護(hù)。想象一下,將從數(shù)據(jù)庫(kù)獲取的數(shù)據(jù)和必要的HTML字符串文字進(jìn)行連接,生成一堆的HTML代碼是多么蛋疼的一件事情。而如果將顯示邏輯移到模板中去,則勢(shì)必極大提高應(yīng)用程序的可維護(hù)性。
模板就是包含響應(yīng)文本的文件,帶有占位符變量的動(dòng)態(tài)部分只在請(qǐng)求上下文中被知道。用真實(shí)的值替換變量并返回最終響應(yīng)字符串,這個(gè)過程稱為渲染。對(duì)于渲染模板任務(wù),F(xiàn)lask使用強(qiáng)大的模板引擎Jinja2。
1、Jinja2模板引擎Jinja2模板最簡(jiǎn)單的形式就是一個(gè)包含響應(yīng)文本的文件。示例3-1展示了Jinja2模板匹配示例2-1中index()視圖函數(shù)響應(yīng)。
示例3-1. templates/index.html:Jinja2模板
htmlHello World!
示例2-2中視圖函數(shù)user()返回的響應(yīng)有一個(gè)動(dòng)態(tài)部分,該部分由一個(gè)變量代表。示例3-2展示模板實(shí)現(xiàn)該響應(yīng)。
示例3-2. templates/user.html:Jinja2模板
htmlHello, {{ name }}!
Flask默認(rèn)會(huì)在應(yīng)用程序的templates子目錄中尋找模板。下個(gè)版本的hello.py,你需要將之前定義的index.html和user.html模板存放到新的templates文件夾下。
應(yīng)用程序中的視圖函數(shù)需要修改來(lái)渲染這些模板。示例3-3中會(huì)展示這些變化。
示例3-3. hello.py:渲染模板
pythonfrom flask import Flask, render_template # ... @app.route("/index") def index(): return render_template("index.html") @app.route("/user/") def user(name): return render_template("user.html", name=name)
render_template函數(shù)由集成Jinja2模板引擎的Flask提供。這個(gè)函數(shù)將模板的文件名作為它的第一個(gè)參數(shù)。任何附加的參數(shù)都是一個(gè)鍵/值對(duì),分別對(duì)應(yīng)被模板引用的變量和真實(shí)值。在這個(gè)示例中,第二個(gè)模板收到name變量。
類似于name=name的關(guān)鍵字參數(shù)在前面的示例中是非常常見的,但如果你不使用就很容易混淆且非常難理解。左邊的“name”代表參數(shù)名稱,一般在模板中用于占位符。右邊的“name”在當(dāng)前范圍內(nèi)是一個(gè)變量,為同名的參數(shù)提供真實(shí)的值。
建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運(yùn)行git checkout 3a來(lái)切換到這個(gè)版本的應(yīng)用程序。
示例3-2的模板中的{{ name }}結(jié)構(gòu)引用一個(gè)變量,特殊的占位符告訴模板引擎,那個(gè)地方的值應(yīng)該從模板被渲染時(shí)提供的數(shù)據(jù)中獲取。
Jinja2識(shí)別任何類型的變量,包括復(fù)雜的列表、字典和對(duì)象。下面是一些模板中使用變量的示例:
htmlA value from a dictionary: {{ mydict["key"] }}.
A value from a list: {{ mylist[3] }}.
A value from a list, with a variable index: {{ mylist[myintvar] }}.
A value from an object"s method: {{ myobj.somemethod() }}.
變量可以通過filters來(lái)修改,以|為分隔符添加在變量名后。例如,下面的模板展示變量大寫:
htmlHello, {{ name|capitalize }}
表格3-1列出一些常用的Jinja2過濾器。
表格3-1. Jinja2變量過濾器
safe是比較有趣的一個(gè)過濾器。出于安全考慮,默認(rèn)情況下,Jinja2會(huì)轉(zhuǎn)義所有變量。例如,如果設(shè)置變量的值為"Hello
",Jinja2將渲染字符串為"Hello
",這將使得h1元素顯示出來(lái)且不能被瀏覽器解釋。很多時(shí)候有必要顯示存儲(chǔ)在變量中的HTML代碼,對(duì)于這些情況就可以使用safe過濾器。
警告:永遠(yuǎn)不要在不信任的值中使用safe過濾器,例如用戶在web表單中輸入的文本。
完整的過濾器列表可以從Jinja2官方文檔中獲取。
Jinja2提供一些控制結(jié)構(gòu)用于改變模板流。這一節(jié)用簡(jiǎn)單例子來(lái)介紹一些最有用的。
下面的示例展示條件語(yǔ)句是怎樣在模板中使用的:
{ % if user %} Hello, {{ user }}! { % else %} Hello, Stranger! { % endif %}
渲染一列元素在模板中是經(jīng)常用到的。這個(gè)示例展示如何使用for循環(huán)做到這些:
html{% for comment in comments %}
- {{ comment }}
{% endfor %}
Jinja2同樣支持宏,這和Python代碼中的函數(shù)很像。例如:
html{% macro render_comment(comment) %}{{ comment }} {% endmacro %}{% for comment in comments %} {{ render_comment(comment) }} {% endfor %}
為了提高宏的復(fù)用性,可以將它們保存為多帶帶的文件,然后在所有需要的地方import即可:
html{% import "macros.html" as macros %}{% for comment in comments %} {{ macros.render_comment(comment) }} {% endfor %}
需要在一些地方重復(fù)使用的模板代碼可以保存為一個(gè)多帶帶的文件,所有模板都可以include它來(lái)避免重復(fù):
{% include "common.html" %}
另一個(gè)強(qiáng)大的復(fù)用方式是通過模板繼承,這類似于Python代碼中類的繼承。首先創(chuàng)建一個(gè)名為base.html的基礎(chǔ)模板:
html {% block head %}{% block title %}{% endblock %} - My Application {% endblock %} {% block body %} {% endblock %}
這里block標(biāo)簽定義的派生模板是可變的。在這個(gè)示例中,有head、title、body塊;注意title包含在head中。下面的示例是一個(gè)基礎(chǔ)模塊的派生模塊:
html{% extends "base.html" %} {% block title %}Index{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block body %}Hello, World!
{% endblock %}
extends指令定義這個(gè)模板由base.html派生。緊隨這個(gè)指令之后的是三個(gè)在基礎(chǔ)模板中定義的塊,它們將在合適的位置插入。注意在基礎(chǔ)模板中新定義的head塊是不為空的,所以使用super() 保留原來(lái)的內(nèi)容。
本節(jié)呈現(xiàn)的所有控制結(jié)構(gòu)的實(shí)際運(yùn)用將在后面展示,你會(huì)有機(jī)會(huì)看到它們是怎樣工作的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/37435.html
摘要:每個(gè)表單域都可以連接到一個(gè)或多個(gè)是一個(gè)用于檢查用戶提交的輸入是否合法的函數(shù)。表單域構(gòu)造函數(shù)的第一個(gè)參數(shù)是一個(gè),在渲染表單到時(shí)會(huì)使用。驗(yàn)證確保提交的表單域不為空。表單域驗(yàn)證都是直接從包中導(dǎo)入。表格展示了一組支持的標(biāo)準(zhǔn)表單域。 第二章中介紹的request對(duì)象公開了所有客戶端發(fā)送的請(qǐng)求信息。特別是request.form可以訪問POST請(qǐng)求提交的表單數(shù)據(jù)。 盡管Flask的request...
摘要:示例使用的模板的指令通過從引用來(lái)實(shí)現(xiàn)模板的繼承。上面的模板定義了三個(gè),分別命名為和。同時(shí)返回相應(yīng)錯(cuò)誤的數(shù)字狀態(tài)碼。示例帶有導(dǎo)航欄的基礎(chǔ)應(yīng)用程序模板這個(gè)模板中的塊中只是一個(gè)名為的元素,它包含了在派生模板中定義的名為的空。 2、集成Twitter Bootstrap的Flask-Bootstrap Bootstrap是Twitter的一個(gè)開源框架,提供用戶交互組件來(lái)創(chuàng)建一個(gè)清新且有吸引力...
摘要:如果路由重組,模板中的鏈接將被打斷而變得無(wú)法訪問。靜態(tài)文件應(yīng)用程序不僅僅是由代碼和模板組成。當(dāng)服務(wù)器收到來(lái)自之前示例的,它會(huì)產(chǎn)生一個(gè)響應(yīng)包含的文件內(nèi)容。一個(gè)優(yōu)雅的解決方案是允許服務(wù)器只發(fā)送時(shí)間給瀏覽器,由瀏覽器轉(zhuǎn)為當(dāng)?shù)貢r(shí)間并渲染。 4、鏈接 任何應(yīng)用程序都有多個(gè)路由,必然需要包含鏈接來(lái)連接不同的頁(yè)面,例如導(dǎo)航欄。 在模板中,對(duì)于簡(jiǎn)單的路由直接寫URLs做鏈接是非?,嵥槁闊┑?,而給帶...
摘要:函數(shù)攜帶目的地址主題郵件體模板和一組關(guān)鍵字參數(shù)。許多擴(kuò)展操作是在假設(shè)有活動(dòng)的應(yīng)用程序和請(qǐng)求上下文的情況下進(jìn)行的。但是當(dāng)函數(shù)在一個(gè)不同的線程上執(zhí)行,應(yīng)用程序上下文需要人為地創(chuàng)建使用。例如,執(zhí)行函數(shù)可以將郵件發(fā)送到的任務(wù)隊(duì)列中。 許多類型的應(yīng)用程序都會(huì)在某些事件發(fā)生的時(shí)候通知用戶,常用的溝通方法就是電子郵件。盡管在Flask應(yīng)用程序中,可以使用Python標(biāo)準(zhǔn)庫(kù)中的smtplib包來(lái)發(fā)送電...
摘要:局部變量用于保存從表單中接收到的名字,初始化時(shí)變量為。在語(yǔ)句中,這個(gè)名字被賦值給局部變量且表單域的數(shù)據(jù)屬性通過賦值為空字符串而被清除。示例重定向和用戶會(huì)話在上一個(gè)版本中,局部變量用于保存用戶在表單中輸入的姓名。 4、視圖函數(shù)中的表單操作 在新版本的hello.py中,index()視圖函數(shù)渲染表單并接收其數(shù)據(jù)。示例4-4展示更新后的index()視圖函數(shù)。 示例4-4. hello...
閱讀 1035·2019-08-30 14:24
閱讀 1176·2019-08-30 14:13
閱讀 1895·2019-08-29 17:21
閱讀 2874·2019-08-29 13:44
閱讀 1756·2019-08-29 11:04
閱讀 552·2019-08-26 10:44
閱讀 2665·2019-08-23 14:04
閱讀 994·2019-08-23 12:08