Flask,模板,過濾器,靜態文件
在前面的示例中,視圖函數的主要作用是生成請求的響應,這是最簡單的請求。實際上,視圖函數有兩個作用:處理業務邏輯和返回響應內容。在大型應用中,把業務邏輯和表現內容放在一起,會增加代碼的複雜度和維護成本。
本文介紹的模板,它的作用即是承擔視圖函數的另一個作用,即返回響應內容。 模板其實是一個包含響應文本的文件,其中用佔位符(變量)表示動態部分,告訴模板引擎其具體值需要從使用的數據中獲取。使用真實值替換變量,再返回最終得到的字符串,這個過程稱爲“渲染”。
Flask使用Jinja2這個模板引擎來渲染模板。Jinja2能識別所有類型的變量,Flask提供的render_template函數封裝了該模板引擎,render_template函數的第一個參數是模板的文件名,後面的參數都是鍵值對,表示模板中變量對應的真實值。
模板默認存放在項目templates目錄下,可在實例化Flask對象時使用template_folder指定其它目錄。
Jinja2模板引擎使用以下分隔符從HTML轉義。
{% ... %}:用於語句,if/for等控制流語句
{{ ... }}:用於變量/表達式顯示輸出
{# ... #}:用於未包含在模板輸出中的註釋
# ... #:用於行語句
下面的示例中,演示了在模板中使用if條件語句。hello()函數的URL規則接受整數參數。它被傳遞到hello.html模板。其中,比較接收的數字(marks)的值(大於或小於50),因此有判斷條件地呈現響應內容。
WC_public_flask.py
from flask import Flask, render_template, request
app = Flask(__name__, template_folder='templates')
@app.route('/hello/<int:score>')
def hello(score):
return render_template('hello.html', marks=score)
if __name__ == '__main__':
app.run(debug = True)
hello.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if marks >= 50 %}
<h1>you result pass !</h1>
{% else %}
<h1>you result fail</h1>
{% endif %}
</body>
</html>
運行Python腳本並訪問URL http://localhost/hello/60,然後訪問http://localhost/hello/30,以查看HTML的輸出是否有條件地更改。
接下我們看一下for循環HTML示例:
WC_public_flask.py
from flask import Flask, render_template, request
app = Flask(__name__, template_folder='templates')
@app.route('/hello')
def hello():
data = {'c++':90,'c':95,'ruby':45}
return render_template('hello.html', marks = data)
if __name__ == '__main__':
app.run(debug = True)
hello.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for name,score in marks.items() %}
<h2>{{ name }}:{{ score }}</h2>
{% endfor %}
</body>
</html>
for語句放在了{%%}內,name,score放在了{{}}內,運行瀏覽器輸入:http://127.0.0.1:5000/result,效果如下:
過濾器
過濾器的本質就是函數。有時候我們不僅僅只是需要輸出變量的值,我們還需要修改變量的顯示,甚至格式化、運算等等,這就用到了過濾器。 過濾器的使用方式爲:變量名 | 過濾器。 過濾器名寫在變量名後面,中間用 | 分隔。如:{{variable | capitalize}},這個過濾器的作用:把變量variable的值的首字母轉換爲大寫,其他字母轉換爲小寫。 其他常用過濾器如下:
字符串操作:
safe:禁用轉義;
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把變量值的首字母轉成大寫,其餘字母轉小寫;
<p>{{ 'hello' | capitalize }}</p>
lower:把值轉成小寫;
<p>{{ 'HELLO' | lower }}</p>
upper:把值轉成大寫;
<p>{{ 'hello' | upper }}</p>
title:把值中的每個單詞的首字母都轉成大寫;
<p>{{ 'hello' | title }}</p>
trim:把值的首尾空格去掉;
<p>{{ ' hello world ' | trim }}</p>
reverse:字符串反轉;
<p>{{ 'olleh' | reverse }}</p>
format:格式化輸出;
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML標籤都刪掉;
<p>{{ '<em>hello</em>' | striptags }}</p>
列表操作
first:取第一個元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
last:取最後一個元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
length:獲取列表長度
<p>{{ [1,2,3,4,5,6] | length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
當模板內置的過濾器不能滿足需求,可以自定義過濾器。自定義過濾器有兩種實現方式:一種是通過Flask應用對象的add_template_filter方法。還可以通過裝飾器@app.template_filter(‘自定義過濾器的名字’)來實現自定義過濾器。
注意:如果不傳入參數,過濾器的名字就是函數的名字。
內置的過濾器就不做示例了,我們看一下自定義過濾器的使用:
WC_public_flask.py
from flask import Flask, render_template, request
app = Flask(__name__, template_folder='templates')
@app.route('/hello', methods=['POST','GET'])
def hello():
if request.method == 'POST':
name = request.form['nm']
return render_template('hello.html', data = name)
else:
return render_template('hello.html')
@app.template_filter('addinfo')
def add_info(arg):
return 'hello {} ! this is template filter '.format(arg)
if __name__ == '__main__':
app.run(debug = True)
hello.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if data %}
<h2>{{ data | addinfo }}</h2>
{% endif %}
<form action = "http://localhost:5000/hello" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
運行效果如下:
靜態文件
Web應用程序通常需要靜態文件,例如javascript文件或支持網頁顯示的CSS文件。通常,配置Web服務器併爲您提供這些服務,但在開發過程中,這些文件是從您的包或模塊旁邊的static文件夾中提供,它將在應用程序的/static中提供。
特殊端點’static’用於生成靜態文件的URL。
在下面的示例中,在index.html中的HTML按鈕的OnClick事件上調用hello.js中定義的javascript函數,該函數在Flask應用程序的“/”URL上呈現。
WC_public_flask.py
from flask import Flask, render_template, request
app = Flask(__name__, template_folder='templates', static_folder='static')
@app.route('/')
def hello():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug = True)
index.html
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript"
src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayhello()" value = "Say Hello" />
</body>
</html>
hello.js
function sayhello() {
alert('Hello World')
}
效果如下:
這一章就到這裏了,下一章我們瞭解一下Flask如何使用數據庫。