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