Flask基礎快速上手
0. URL傳參
0.1 URL傳參有什麼用?
可以使用相同的URL指定不同的參數,來訪問不同的內容。
0.2 URL傳參的語法是什麼?
傳遞參數的語法是:'/<參數名>/'
。
注意2點:
參數需要放在一對<>
(尖括號)內;
視圖函數中需要設置同URL中相同的參數名。
0.3 URL傳參的2個案例
例1:
### 從Flask框架中導入Flask類
from flask import Flask
### 傳入__name__初始化一個Flask實例
app = Flask(__name__)
### 這個路由將根URL映射到hello_world函數上
@app.route('/')
def hello_world(): ### 定義視圖函數
return '這是url傳參演示!' ### 返回響應對象
### 定義路由,傳遞的參數名是name,因此函數的形參也是name。視圖函數的名字不做要求,隨意 = 不重名 + 見名知意
@app.route("/user/<name>")
### 定義試圖函數fun01,形參是name
def fun01(name):
return f"接收到的名稱是:{name}"
### 如果該模塊直接被執行,那麼__name__ == '__main__'條件爲真,開始執行下面代碼。當該模塊被導入時,無法執行代碼。
if __name__ == '__main__':
### 指定默認主機是127.0.0.1,port是5000
app.run(debug=True)
將上述代碼中的【@app.route("/user/")】改爲【@app.route("/")】試試:
例2:
### 從Flask框架中導入Flask類
from flask import Flask
### 傳入__name__初始化一個Flask實例
app = Flask(__name__)
### 這個路由將根URL映射到hello_world函數上
@app.route('/')
def hello_world(): ### 定義視圖函數
return '這是url傳參演示!' ### 返回響應對象
### 定義路由,傳遞的參數名是name,因此函數的形參也是name。視圖函數的名字不做要求,隨意 = 不重名 + 見名知意,比如fun01
@app.route("/user/<name>")
### 定義試圖函數fun01,形參是name
def fun01(name):
return f"接收到的名稱是:{name}"
### 定義路由,傳遞的參數名是【整型】的id,因此函數的形參也是id,視圖函數的名字不做要求,隨意 = 不重名 + 見名知意,比如fun02
@app.route("/news/<int:id>")
def fun02(id):
return f"接收到的id是:{id}"
### 如果該模塊直接被執行,那麼__name__ == '__main__'條件爲真,開始執行下面代碼。當該模塊被導入時,無法執行代碼。
if __name__ == '__main__':
### 指定默認主機是127.0.0.1,port是5000
app.run(debug=True)
1. URL反轉
1.1 URL反轉是什麼?
有時候,在作網頁重定向或是模板文件時需要使用在視圖函數中定義的URL,我們必須根據視圖函數名稱得到當前所指向的URL,這就是URL反轉。
正轉:通過url查看視圖函數中的內容,比如輸入:http://127.0.0.1:5000/,看到hello world。
反轉:通過視圖函數名字得到視圖函數指向的url。
用途:頁面跳轉和重定向
1.2 URL反轉的語法
語法:導入url_for,url_for(‘視圖函數名字’,參數)
1.3 URL反轉的使用
### 導入Flask及url_for模塊
from flask import Flask,url_for
### Flask初始化
app = Flask(__name__)
### 定義根路由
@app.route("/")
def index():
### fun01是視圖函數的名字。 id的類型要相同。
### 哪裏有url_for,哪裏就有URL反轉
url1 = (url_for("fun01",id = 12580))
return f"URL反轉的內容是:{url1}"
###只是定義路由。id的類型要相同。
@app.route("/news/<int:id>")
###函數名fun01與url_for的第一個參數必須同名。
def fun01(id):
return f"你的請求參數是:{id}"
### 如果該模塊直接被執行,那麼執行代碼塊,如果該模塊被導入,那麼不執行代碼塊
if __name__ == "__main__":
app.run(debug = True)
2. 頁面跳轉和重定向
用戶在訪問某個頁面的時候,我們希望他登錄後才能訪問該頁面,如果此時他沒有登錄,系統就讓瀏覽器由當前頁面跳轉到登錄頁面,這裏就涉及頁面重定向問題。所謂頁面重定向,就是用戶在打開某個頁面的時候,我們期望頁面跳轉到另一個指定的頁面,讓用戶完成某種操作或執行某個動作。
Flask中提供了重定向函數redirect(),該函數的功能就是跳轉到指定的URL。
### 導入Flask和url_for和redirect模塊
from flask import Flask,url_for,redirect
### Flask初始化
app = Flask(__name__)
### 根路由
@app.route("/")
### 定義試圖函數
def index():
### 打印輸出
print("首先訪問了index()這個函數")
### URL反轉
url1 = url_for("user_login")
### 網頁重定位
return redirect(url1)
### 定義路由
@app.route("/user_login")
### 定義試圖函數
def user_login():
### 返回值
return "這是用戶登錄的頁面,請你登錄才能訪問首頁"
### 當直接執行該模塊時,條件爲真,執行代碼塊;當被當做模塊導入時,代碼不執行
if __name__ == '__main__':
app.run()
2.1 問題
(1)什麼是Flask?(2)URL如何傳遞參數?(3)網頁如何重定向?
3.Jinja 2 模板引擎
3.1 模板引擎是什麼及使用
在Flask中通常使用Jinja 2模板引擎來實現複雜的頁面渲染。
templates文件夾下的index.html配置如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><!-- 設置網頁編碼-->
<title>這是首頁</title><!-- 設置網頁標題-->
<h1>這是首頁文字</h1><!-- 設置H1標題-->
</head>
<body>
</body>
</html>
templates文件夾下的user.html配置如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><!-- 設置網頁編碼-->
<title>這是用戶中心</title><!-- 設置網頁標題-->
<h1>這是用戶中心!</h1><!-- 設置h1標題-->
</head>
<body>
</body>
</html>
app.py配置如下:
# 導入flask模塊
from flask import Flask
# 導入render_template模塊
from flask import render_template
# Flask初始化
app = Flask(__name__)
# 定義根路由
@app.route("/")
# 定義視圖函數
def index():
# 使用render_template()方法渲染模板
return render_template("index.html")
#定義路由,實踐時比如/user/yjg,比如/user/yj
@app.route("/user/<username>")
#定義視圖函數
def user(username):
# 使用render_template()方法渲染模板
return render_template("user.html")
# 當直接執行該模塊時,條件爲真,執行代碼塊;當該模塊被其他模塊調用時,不執行代碼塊
if __name__ == '__main__':
app.run(debug = True)
運行結果如下:
Flask通過render_template()函數來實現模板的渲染。要使用Jinja 2模板引擎,需要使用fromflask import render_template命令導入render_template函數。在視圖函數的return方法中,render_template()函數的首個參數聲明使用哪一個模板文件。
注意:在render_template()函數中,有一個參數是用來聲明使用哪個靜態文件,除此參數之外,還可以有多個參數。
3.2 向模板中傳遞參數
Flask提供Jinja 2模板引擎來渲染模板的同時,還可以將程序中的參數或變量值傳遞給指定的模板進行渲染。
templates文件夾下的index.html配置如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><!-- 設置網頁編碼-->
<title>這是首頁</title><!-- 設置網頁標題-->
<h1>這是首頁文字</h1><!-- 設置H1標題-->
</head>
<body>
</body>
</html>
templates文件夾下的user.html配置如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><!-- 設置網頁編碼-->
<title>這是用戶中心</title><!-- 設置網頁標題-->
<h1>歡迎您:{{ name }}</h1><!-- 設置h1標題-->
</head>
<body>
</body>
</html>
app.py配置如下:
# 導入flask模塊
from flask import Flask
# 導入render_template模塊
from flask import render_template
# Flask初始化
app = Flask(__name__)
# 定義根路由
@app.route("/")
# 定義視圖函數
def index():
# 使用render_template()方法渲染模板
return render_template("index.html")
#定義路由,實踐時比如/user/yjg
@app.route("/user/<username>")
#定義視圖函數
def user(username):
# 使用render_template()方法渲染模板並向模板傳遞參數
return render_template("user.html",name = username)
# 當直接執行該模塊時,條件爲真,執行代碼塊;當該模塊被其他模塊調用時,不執行代碼塊
if __name__ == '__main__':
app.run(debug = True)
運行程序,得到如圖所示結果。
render_template()函數第一個參數是指定模板文件的名稱,比如這裏的index.html和user.html。render_template()函數的第二個參數爲可選項,可以爲空。比如index()視圖函數中的render_template(‘index.html’),這裏第二個參數爲空。第二個參數不爲空的話,一般用於向模板中傳遞變量。這裏傳遞變量,一般是以鍵值對方式進行的。
def index():
title = "python的鍵值對"
author = "CSDN_Keegan"
# 使用render_template()方法渲染模板
return render_template("index.html",var1 = title,var2 = author)
用上述代碼替換index()視圖函數代碼,在index.html的和區域增加下面的代碼:
<body>
<p>傳過來的標題是:{{ var1 }}</p><!-- 文字原樣輸出-->
<br>{#br表示網頁中的回車#}
<p>傳過來的作者是:{{ var2 }}</p>
</body>
模板中接收變量值,需要把變量放在{{}},比如{{var1}}等。模板中如果要寫註釋,格式爲{##},比如這裏的{#br表示網頁中的回車#}。
如果視圖函數中有多個變量值都需要傳遞給模板該怎麼辦呢?
可以使用**locals()方法,例如:
def index():
title = "python的鍵值對"
author = "CSDN_Keegan"
# 使用render_template()方法渲染模板
return render_template("index.html",**locals())
實際上是將 return render_template(‘index.html’,var1=title,var2=author)這行代碼替換爲
return render_template(‘index.html’,**locals())。
將模板文件index.html中的{{var1}}
{{var2}}替換爲{{title}}
{{author}}即可。
<body>
<p>傳過來的標題是:{{ title }}</p><!-- 文字原樣輸出-->
<br><!--br表示網頁中的回車 -->
{#br表示網頁中的回車#}
<p>傳過來的作者是:{{ author }}</p>
</body>
**注意:在render_template()函數中,如果要給模板傳遞【全部】的本地變量,可以使用【locals()】方法,此時,在模塊中可以直接使用{{title}}和{{author}}來直接使用變量。
3.3 模板中控制語句之if語句
在Jinja 2模板引擎中也可以使用if和for循環控制語句,控制模板渲染的方向。模板引擎中,if和for語句中應該放到{%%}中。
index.html
<!DOCTYPE html><!---->
<html lang="en">
<head>
<meta charset="UTF-8"><!--設定網頁編碼-->
<title>Title</title><!--設定網頁標題-->
</head>
<body>
{% if name %}<!--name值是否存在-->
<h1>產生的隨機數有效!</h1><!--如果是存在的,則輸出這句話-->
{% else %}<!--如果是不存在的-->
<h1>產生的隨機數無效</h1>
{% endif %}<!--結束if-->
</body>
</html>
app.py
# 導入Flask及render_template模塊
from flask import Flask,render_template
# 導入random模塊
import random
# Flask初始化
app = Flask(__name__)
# 定義路由
@app.route('/')
# 定義視圖函數
def hello_world():
# 產生0-1之間的整數
rand1 = random.randint(0,1)
return render_template("index.html",name = rand1)
if __name__ == '__main__':
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if name == 1 %}
<h1>恭喜,你獲得了一等獎</h1>
{% elif name == 2 %}
<h1>恭喜,你獲得了二等獎</h1>
{% else %}
<h1>恭喜,抽到了三等獎</h1>
{% endif %}
{{ name }}
</body>
</html>
app.py
from flask import Flask,render_template
import random
app = Flask(__name__)
@app.route('/')
def hello_world():
rand1 = random.randint(1,3)
return render_template("index.html",name = rand1)
if __name__ == '__main__':
app.run(debug=True)
在模板中,儘量少使用多層嵌套的if…else…語句,往往會因爲縮進出現這樣或那樣的問題。儘量多用if…elif…else…的結構(即多個elif),這一系列條件判斷會從上到下依次判斷,如果某個判斷爲True,執行完對應的代碼塊,後面的條件判斷就會直接忽略,不再執行。
注意:模板的表達式都是包含在分隔符”{{}}”內的;控制語句都是包含在分隔符”{%%}”內的;模板中的註釋是放在包含在分隔符”{##}”內,支持塊註釋。
3.4 模板中控制語句之for語句
for循環語句是Python中的一個循環控制語句,任何有序的序列對象內的元素都可以遍歷,比如字符串、列表、元組等可迭代對像。for循環的語法格式如下:
shop.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
<thead>
<th>商品名稱</th>
<th>商品價格</th>
</thead>
<tbody>
<meta charset="UTF-8">
{% for goods in goods %}
<tr>
<td>{{ goods.name }}</td>
<td>{{ goods.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
goods = [{"name":"陽光男孩外套春秋韓版寬鬆2020新款上市","price":149.00},
{"name":"黑色時尚外套女春秋版2020新款韓版休閒","price":100.00},
{"name":"復古牛仔外套男2020新款","price":136.00},
{"name":"新百倫耐穿2020新款","price":265.00}]
return render_template("shop.html",**locals())
if __name__ == '__main__':
app.run(debug=True)
注意:在模板中,使用if條件判斷語句或者是for循環語句可以幫助開發者更好地渲染模板。通過{%邏輯表達式%}可以實現代碼的嵌套,其語法與Python語法基本一致,但是必須要包含在{%%}內部。
3.5 Flask的過濾器
過濾器本質上是一個轉換函數,有時候我們不僅需要輸出變量的值,還需要把某個變量的值修改後再顯示出來,而在模板中不能直接調用Python中的某些方法,這麼這就用到了過濾器。
3.5.1 常見的過濾器
1.與字符串操作相關的過濾器
2.對列表進行操作相關的過濾器
3.對數值進行操作相關的過濾器
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>過濾器</title>
</head>
<body>
<p>{{ age|abs }}</p>
<p>{{ "hello"|capitalize }}</p>
<p>{{ "hello"|replace("h","x") }}</p>
<p>{{ [01,80,42,44,77]|first }}</p>
<p>{{ [01,80,42,44,77]|last }}</p>
<p>{{ [01,80,42,44,77]|count }}</p>
<p>{{ [01,80,42,44,77]|sort }}</p>
<p>{{ [01,80,42,44,77]|join(",")}}</p>
<p>{{ 18.888|round(2,"floor")}}</p>
<p>{{ 18.888|round }}</p>
<p>{{ -2|abs }}</p>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
student = {
"name":"keegan",
"age":-18
}
return render_template("index.html",**student)
if __name__ == '__main__':
app.run()
3.5.2 自定義過濾器
過濾器的實質就是一個轉換函數,我們其實完全可以寫出屬於自己的自定義過濾器。通過調用應用程序實例的add_template_filter方法實現自定義過濾器。該方法第一個參數是函數名,第二個參數是自定義的過濾器名稱。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.line{
display: inline-block;
height: 1px;
width: 100%;
background: #00CCFF;
overflow: hidden;
vertical-align: middle;
}
</style>
</head>
<body>
<meta charset="UTF-8">
{% for goods in goods %}
{#對列表進行遍歷#}
<li style = "list-style-type:none">{{ goods.name }}
<span class = "{{ loop.index | index_class}}"></span>
</li>
{% endfor %}
</body>
</html>
上面的代碼對傳遞過來的列表進行遍歷,每3行輸出一條分割線,分割線的樣式見style裏的代碼。
app.py
from flask import Flask,render_template
import sys
app = Flask(__name__)
@app.route('/')
def hello_world():
### 定義商品列表goods
goods = [{"name":"三國痣"},
{"name":"y語言核心編程"},
{"name":"阿里巴巴和四十大盜"},
{"name":"榮耀25 pro"}]
return render_template("index.html",**locals())
def do_index_class(index):
### 每個三行輸出輸出line
if index % 3 == 0:
return "line"
### 使用自定義過濾器添加CSS
app.add_template_filter(do_index_class,"index_class")
if __name__ == '__main__':
app.run()
3.6 宏是什麼及使用
Jinja 2中的宏功能有些類似於傳統程序語言中的函數,它跟Python中的函數類似,可以傳遞參數,但是【不能】有返回值,可以將一些經【常用】到的代碼片段放到【宏】中,然後把一些【不固定】的值抽取出來作爲一個【變量】。
3.6.1 宏是什麼?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏的定義和使用</title>
</head>
<body>
{#宏的定義#}
{% macro input(name,type="text",value = "") -%}
<input type="{{ type }}" name = "{{ name }}" value = "{{ value }}">
{%- endmacro %}
{#宏的使用#}
<div style = "color:#0000FF">
<p>用戶名:{{ input("username") }}</p>
<p>密碼:{{ input("password",type = "password") }}</p>
<p>登錄:{{ input("submit",type = "submit",value = "登錄") }}</p>
</div>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug=True)
注意:上面將input標籤定義成了一個宏,根據實際情況,還可以在宏的定義中加入size和placeholder等屬性,如{%macro input(name,type='text',value='',size=20,placeholder="請在這裏輸入用戶名")-%}。<input type="{{type}}"name="{{name}}"value="{{value}}"size="{{size}}",placeholder="{{placeholder}}">
3.6.2 宏的導入
一個宏可以被不同的模板使用,所以我們建議將其聲明在一個單獨的模板文件中。需要使用時導入即可,而導入的方法類似於Python中的import。
form.html
{% macro input(name,type = "text",value = "") -%}
<input type = "{{ type }}" name = "{{ name }}" value = "{{ value|e }}">
{%- endmacro %}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏的導入</title>
</head>
<body>
{% import "form.html" as form %}
{#導入宏#}
<div style = "color:#0000FF"></div>
{#使用宏定義用戶名輸入框#}
<p>用戶名:{{ form.input("username") }}</p>
{#使用宏定義輸入密碼輸入框#}
<p>密碼:{{ form.input("password",type = "password" )}}</p>
<p>登錄:{{ form.input("submit",type = "submit",value = "登錄") }}</p>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template("index.html")
if __name__ == '__main__':
app.run()
注意:{%import’form.html’as form%}這種導入方法也可以使用{%from’form.html’importinput%}實現導入。
用戶名:{{form.input(‘username’)}}
中的form需要去掉了,直接寫成用戶名:{{input(‘username’)}}
。3.6.3 include的使用
宏文件中引用其他宏,可以使用include語句。include語句可以把一個模板引入到另外一個模板中,類似於把一個模板的代碼複製到另外一個模板的指定位置。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.header{
width:100%;
height:40px;
margin: 20px 20px;
}
.footer{
width:100%;
height:40px;
margin: 20px 20px;
}
.content{
width:100%;
heigth:40px;
margin: 20px 20px;
}
</style>
</head>
<body>
{% include "header.html" %}
<div class = "content">
這是網頁內容
</div>
{% include "footer.html" %}
</body>
</html>
header.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<div class = "header">
這是網頁頭部
</div>
<body>
</body>
</html>
footer.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class = "footer">
這是網頁尾部
</div>
</body>
</html>
include把一個模板的代碼複製到另外一個模板的指定位置,這裏的{%include''header.html''%}和{%include''footer.html''%}把頭文件和尾部文件引入到index.html文件中。
注意:使用include標籤時是在templates目錄中尋找相應的文件,不要使用相對路徑。
3.7 set和with語句的使用
set與with語句都可以在Jinja 2中定義變量並賦予值。set定義的變量在整個模板範圍內都有效,with關鍵字在定義變量並賦值的同時,限制了with定義變量的作用範圍。
index.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<br>
{#給變量賦值#}
{% set telephone = "1388888888" %}
{#給列表或數組賦值#}
{% set nav = [("index.html","index"),("product.html","product")] %}
{{ telephone }}
<br>
{{ nav }}
<br>
{#with定義的變量的作用範圍在{%with%}和{%endwith%}代碼塊內,在模板的其他地方,引用此變量值無效。#}
{% with pass = 60 %}
{{ pass }}
{% endwith %}
<body>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug=True)
3.8 靜態文件的加載
靜態文件的加載一般需要先新建文件夾static,在文件夾下再新建css、js和images文件夾,在這些文件夾中存放css、js、images,同時要需要使用url_for
函數。
項目目錄結構:
在templates目錄下新建一個名爲index.html的文件,在app.py的視圖函數中使用returnrender_template(‘index.html’)方法來渲染模板。下面分別給出加載JS、圖片和CSS的方法。
(1)加載JS文件在靜態文件index.html中,在之前引入jquery-3.4.1.js文件,具體代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# 加載JS文件#}
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</script>
</head>
<body>
</body>
</html>
(2)加載圖片文件。
<img src="{{ url_for("static",filename = "images/a.jpg")}}"></img>
(3)加載CSS文件。加載外部CSS文件,可以使用下述代碼實現:
{# 加載CSS文件#}
<link rel="stylesheet" href="{{ url_for("static",filename = "css/a.css") }}">
a.css
.img{
BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px;
BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid
}
總代碼:
a.css
.img{
BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px;
BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# 加載JS文件#}
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{# 加載CSS文件#}
<link rel="stylesheet" href="{{ url_for("static",filename = "css/a.css") }}">
</head>
<body>
{#
測試jQuery是否加載
#}
<script>
if(jQuery){
alert("jQuery已加載");
}
else{
alert("jQuery未加載")
}
</script>
<div class = "img">
<img src="{{ url_for("static",filename = "images/a.jpg")}}"></img>
加載圖片
</div>
</body>
</html>
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug=True)
運行結果:
3.9 模板的繼承
一個系統網站往往需要統一的結構,這樣看起來比較“整潔”。比如,一個頁面中都有標題、內容顯示、底部等幾個部分。如果在每一個網頁中都進行這幾部分的編寫,那麼整個網站將會有很多冗餘部分,而且編寫的網頁程序也不美觀。這時可以採用模板繼承,即將相同的部分提取出來,形成一個base.html,具有這些相同部分的網頁通過繼承base.html來得到對應的模塊。
1.模板的繼承語法模板的繼承語法如下:
在templates目錄中創建index.html、base.html和product.html 3個靜態文件。base.html文件作爲基類,index.html和product.html文件作爲子類,子類去繼承基類的基本內容。
目錄結構:
base.html文件內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %} -我的網站</title>
</head>
<body>
{% block body %}
這是基類裏的內容
{% endblock %}
</body>
</html>
index.html文件內容如下:
{% extends "base.html" %}
{% block title %}網站首頁{% endblock %}
{% block body %}
{{ super() }}
<h4>這是網站首頁的內容</h4>
{% endblock %}
product.html文件的內容:
{% extends "base.html" %}
{% block title %} 產品列表頁{% endblock %}
{% block body %}
<h4>這是產品列表頁的內容</h4>
取得網頁標題的內容:
<h4>{{ self.title() }}</h4>
{% endblock %}
app.py文件內容如下:
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
@app.route("/product")
def product():
return render_template("product.html")
if __name__ == '__main__':
app.run(debug = True)
默認情況下,子模板如果實現了父模板定義的block,那麼子模板block中的代碼就會覆蓋父模板中的代碼。如果想要在子模板中仍然保持父摸板中的代碼,那麼可以使用{{super()}}來實現,如index.html中{%block body%}{%endblock%}代碼塊中使用了{{super()}}方法,運行結果如圖所示:
如果想要在一個block中調用其他block中的代碼,可以通過{{self.其他block名稱()}}實現。比如product.html文件中的
{{self.title()}}
方法。運行此代碼,結果如圖所示。注意:模板的繼承可以這麼理解:就是在一個html文檔中已經寫好了框架,然後要往裏面放東西時,先用<%block blockname%><%endblock%>放一個空的塊在裏面作爲基礎模塊,接下來被別的子模塊導入的時候,用子模塊裏相同名稱的模塊替代。
例如: