Python Flask render_template 模板

本篇 ShengYu 介紹 Python Flask render_template 模板,之前已經學習過基本的 Flask 後,利用 return string 將內容渲染在網頁上,但是實際上很少將整個 HTML 寫在 string 裡,這樣 Python 原始碼將變得很龐大難以維護,本篇介紹 render_template 來做樣板的渲染。接下來就來學習用模板來渲染網頁。

Flask render_template

先以一個簡單的 Flask 範例來學習模板,建立好一個 index.html 並放置在 templates 資料夾下,

flask-templete/templates/index.html
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask</title>
</head>
<body>
<h1>Flask</h1>
<p>Hello World</p>
</body>
</html>

專案資料夾的目錄如下,

1
2
3
4
flask-templete
├── main.py
└── templates
└── index.html

在 Python 中產生 HTML 是件麻煩的事,因為要處理 HTML Escape 轉義的事情,但 Flask 使用 Jinja2 做為模板引擎自動地處理了這些事情,Flask 是使用 render_template() 函式來渲染模板,在使用前先記得 from flask import render_template 匯入模組,新增一個 @app.route('/') 裝飾器綁訂 index() 函式然後使用 render_template('index.html') 來渲染這個 index.html,當有 / 請求時,Flask 會先到 templates 資料夾去找相對應的 html,本範例為 index.html,如果找不到的話會出現 jinja2.exceptions.TemplateNotFound 的錯誤訊息字樣,如果有開啟 debug 模式 debug=True 可以在瀏覽器上看到錯誤訊息。

flask-templete/main.py
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
return render_template('index.html')

if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)

瀏覽器開啟的畫面如下,

Flask render_template + 傳遞參數

在之前我們介紹過,要將網址 URL 當成參數使用的話可以透過下面這種寫法,在 route() 裡的變數要用左右箭號 <> 來包住,預設為字串,Flask 總共的支援的類型有 str、int、float、path,分別的寫法為 @app.route('/<str:xxx>')@app.route('/<int:xxx>')@app.route('/<float:xxx>')@app.route('/<path:xxx>'),以下示範取得 URL 的 /user/<username> 並且將 username 變數回應回去。

python3-flask-url-args.py
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask

app = Flask(__name__)

@app.route('/user/<username>')
def index(username):
return '<p>Hi ' + username + '</p>'

if __name__ == "__main__":
app.run(debug=True)

瀏覽器開啟的畫面如下,

但如果想從 render_template() 傳遞參數進 index.html 的話,就用在 index.html 用特殊的語法表示參數,語法為雙大括號包住參數名稱,如下例 index.html 的 username

flask-templete2/templates/index.html
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flask</title>
</head>
<body>
<h1>Flask</h1>
<p>Hi {{ username }}</p>
</body>
</html>

瀏覽 http://127.0.0.1:5000/ 會將 username 變數初始化成 shengyu 再傳給 render_template()

flask-templete2/main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
username = 'shengyu'
return render_template('index.html', username=username)

if __name__ == "__main__":
app.run(debug=True)

瀏覽器開啟的畫面如下,

那是不是可以結合前面的例子將網址 URL 當成參數傳遞到 render_template 呢?,當然可以!以下面例子為例,
瀏覽 http://127.0.0.1:5000/user/shengyu 將導向給 index(username) 函式,之後在函式內將 username 傳給 render_template()

flask-templete3/main.py
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == "__main__":
app.run(debug=True)

結果可以看到 Hi shengyu

但是這樣的話會發現首頁 http://127.0.0.1:5000/ 無法存取,綜合兩種方式變成以下例子,
index() 的參數裡指定 user 等於 unknown 這樣兩種網址都可以存取了,

flask-templete4/main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == "__main__":
app.run(debug=True)

瀏覽器開啟的畫面如下,

樣板裡的條件判斷

這邊將介紹樣板裡的條件判斷寫法,條件判斷寫法搭配組合總共有 if… endif、if… else… endif、if..elif… endif 這幾種,以下示範 if… else… endif 條件判斷的寫法,

flask-templete5/templates/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flask</title>
</head>
<body>
<h1>Flask</h1>
{% if username %}
<p>Hi {{ username }}</p>
{% else %}
<p>Hello World</p>
{% endif %}
</body>
</html>

index(username='unknown') username 的初始值改成 None index(username=None)

flask-templete5/main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == "__main__":
app.run(debug=True)

樣板裡的迴圈

這邊將介紹樣板裡的迴圈寫法,

flask-templete6/templates/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flask</title>
</head>
<body>
<h1>Flask</h1>
{% for i in range(0, number) %}
<p>Hello World, n = {{ i }}</p>
{% endfor %}
</body>
</html>

要在 @app.route() 裡聲明 num 是 int,否則預設會視為字串,

flask-templete6/main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
@app.route('/<int:num>')
def index(num=1):
return render_template('index.html', number=num)

if __name__ == "__main__":
app.run(debug=True)

瀏覽器開啟 http://127.0.0.1:5000/5 的畫面如下,

其它相關文章推薦
下一篇要介紹