目錄
- 一、Flask 基礎
- 二、路由
- 三、模板
一、Flask 基礎
【示例1】撰寫第一個Flask程式,代碼如下:
from flask import Flask # 1.匯入Flask類
"""
2.創建該類的一個實體,第一個引數是應用模塊或者包的名稱,如果使用單一的模塊(如此處),則應該使用__name__,
模塊的名稱將會因其作為單獨應用啟動還是作為模塊匯入而有所不同,這樣Flask才知道到哪去找模板、靜態檔案等,
"""
app = Flask(__name__)
@app.route("/") # 3.使用route()裝飾器函式告訴Flask什么樣的URL能觸發被執行的函式
def index(): # 4.視圖函式,回傳顯示在用戶瀏覽器中的資訊,
return 'Hello Flask!'
# app.debug = True 第一種方式:開啟除錯模式
if __name__ == '__main__':
app.run(debug=True, port=8000) # 第二種方式:作為run()方法的一個引數傳入 也可以設定其他的引數 如埠號
程式執行結果如下:

然后在瀏覽器中,輸入網址:http://127.0.0.1:8000/ ,運行效果如下圖所示:

二、路由
當客戶端(例:Web瀏覽器)把請求發送給 Web 服務器后,Web 服務器再把請求發送給 Flask 程式實體,程式實體需要知道每個 URL 請求運行了哪些代碼,所以保存了一個 URL 到 Python 函式的映射關系,處理URL和函式之間關系的程式稱為路由,
在 Flask 程式中定義路由的最簡便方式,是使用程式實體提供的 app.route 裝飾器,把裝飾的函式注冊為路由,路由映射關系如圖所示:

說明:在 @app.route() 函式中添加 URL 時,URL 有時是變化的,例如,同一作者不同文章的 ID 是變化的,如下:
https://blog.csdn.net/xw1680/article/details/117434720
https://blog.csdn.net/xw1680/article/details/117854388
針對這種情況,可以構造含有動態部分的 URL,也可以在一個函式上附著多個規則,要給 URL 添加變數部分,可以把這些特殊的欄位標記為 <變數名> 的形式,它將會作為命名引數傳遞到函式,如果要對變數名的型別進行限制,則可以用 <變數型別:變數名> 指定一個可選的型別轉換器,
【示例2】根據不同的用戶名引數輸出相應的用戶資訊,代碼如下:
from flask import Flask # 匯入Flask類
app = Flask(__name__)
@app.route("/")
def index():
return 'Hello Flask!'
@app.route("/user/<username>")
def show_user_info(username):
# 顯示該用戶名的用戶資訊
return f"用戶名是:{username}"
@app.route("/post/<int:post_id>") # int轉換器:接收整數,float:同int,但是接收浮點數, path:和默認的相似,但也接收斜線,
def show_post(post_id):
# 根據ID顯示文章,ID是整型資料
return f"ID是:{post_id}"
if __name__ == '__main__':
app.run(debug=True)
瀏覽器中測驗1:

瀏覽器中測驗2:

瀏覽器中測驗3:

瀏覽器中測驗4:

【示例3】模擬登錄成功后頁面跳轉至首頁的效果,代碼如下:
from flask import Flask, url_for, redirect # 匯入Flask類
app = Flask(__name__)
@app.route("/")
def index():
return 'Hello Flask!'
@app.route("/login")
def login():
# 模擬登錄流程
flag = True
# 如果登錄成功,跳轉到首頁
if flag:
return redirect(url_for("index"))
return "登錄頁面"
if __name__ == '__main__':
app.run(debug=True)
運行效果如下圖所示:

總結:使用 url_for 函式可以構造 URL,所以它經常結合 redirect() 函式用來跳轉到構造的 URL 頁面,
# 回傳index函式對應的路由 "/"
url_for('index')
# 回傳show_post函式對應的路由 "/post/2"
url_for('show_post', post_id=2)
# 回傳show_user_info函式對應的路由 "/user/AmoXiang"
url_for('show_user_info', username='AmoXiang')
HTTP(與Web應用會話的協議)有許多不同的訪問 URL 方法,默認情況下,路由只回應 GET 請求,但是通過 route() 裝飾器傳遞 methods 引數可以改變這個行為,例如:
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
do_the_login()
else:
show_the_login_form()
HTTP 方法(也經常被叫作 謂詞 )可以告知服務器,客戶端想對請求的頁面做些什么,常見的方法如下表所示:
| 方法名 | 說明 |
|---|---|
| GET | 瀏覽器告知服務器:只獲取頁面上的資訊并發給我,這是最常用的方法 |
| HEAD | 瀏覽器告訴服務器:欲獲取資訊,但是只關心訊息頭, |
| POST | 瀏覽器告訴服務器:想在URL上發布新資訊,并且,服務器必須確保資料已存盤且僅存盤一次,這是HTML表單通常發送資料到服務器的方法 |
| PUT | 類似POST,但是服務器可能觸發了存盤程序多次,多次覆寫掉舊值,考慮到傳輸中連接可能會丟失,在這種情況下瀏覽器和服務器之間的系統可能安全地第二次接收請求,而不破壞其他東西,因為POST它只觸發一次,所以需要使用PUT |
| DELETE | 洗掉給定位置的資訊 |
| OPTIONS | 給客戶端提供一個敏捷的途徑來弄清這個URL支持哪些HTTP方法,從Flask 0.6開始,實作了自動處理 |
動態 Web 應用也會需要靜態檔案,該檔案通常是 CSS 和 JavaScript 檔案,默認情況下,只要在包中或是模塊的所在目錄中創建一個名為 static 的檔案夾,在應用中使用 /static 即可訪問,例如,Flask_demo 檔案夾為應用目錄,在 Flask_demo 目錄下創建 static 檔案夾,目錄結構如下圖所示:

給靜態檔案生成 URL,可以使用特殊的 static 端點名,瀏覽器中測驗如下:

三、模板
模板是一個包含回應文本的檔案,其中包含用占位變數表示的動態部分,其具體值只在請求的背景關系中才能知道,使用真實值替換變數,再回傳最終得到的回應字串,這一程序稱為渲染,為了渲染模板,Flask 使用了一個名為 Jinja2 的強大模板引擎,
默認情況下,Flask 在程式檔案夾中的 templates 子檔案夾中尋找模板,Flask 使用 render_template() 函式渲染模板,語法如下:
def render_template(template_name_or_list, **context):
注意:render_template 函式需要從 Flask 包中匯入,它的第一個引數是渲染的模板名稱,其余引數為模板中變數的值, 例如:
return render_template('user.html',username=name)
如果在視圖函式中呼叫上面的代碼,則會渲染 templates 目錄下的 user.html 模板檔案,并且將模板檔案中的 {{username}} 使用 name 的值來替換,
【示例4】渲染首頁模板,在 Flask_demo 目錄下創建 templates 檔案夾,并且在 templates 檔案夾下新建 index.html 模板檔案,如下圖所示:

index.html 中代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask 渲染模板案例演示</title>
</head>
<body>
<h1>阿莫的Python每日一練</h1>
<ul id="practice_list">
<li>{{value1}}</li>
<li>{{value2}}</li>
<li>{{value3}}</li>
<li>{{value4}}</li>
</ul>
</body>
</html>
templates_demo.py 中代碼如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
value1 = "Python每日一練(20)-用Python制作mini翻譯器"
value2 = "Python每日一練(19)-通過爬蟲實作GitHub網頁的模擬登錄"
value3 = "Python每日一練(18)-抓取小說目錄和全文"
value4 = "Python每日一練(17)-通過正則運算式快速獲取電影的下載地址"
# value1=value1 關鍵字引數
# 左邊的value1 ==> 引數名,對應模板中的占位符
# 右邊的value1 ==> 當前作用域中的變數,表示這個引數的值
return render_template("index.html", value1=value1, value2=value2, value3=value3, value4=value4)
if __name__ == '__main__':
app.run(debug=True)
運行效果如下圖所示:

Jinja2 能識別所有型別的變數,甚至是一些復雜的型別,例如串列、字典和物件,在模板中使用變數的一些示例如下:
<li>從串列中取一個值:{{value5[2]}}</li>
<li>從串列中取一個帶索引的值:{{value5[index]}}</li>
<li>從字典中取一個值:{{my_dict['key']}}</li>
<li>從物件的方法中取一個值:{{obj.method()}}</li>
可以使用過濾器修改變數,過濾器名添加在變數名之后,中間使用豎線分隔,例如,下述模板以首字母大寫形式顯示變數 name 的值:
<li>Hello, {{name|capitalize}}</li>
Jinja2 提供的部分常用過濾器如下表所示:
| 名稱 | 說明 |
|---|---|
| safe | 渲染值時不轉義 |
| capitalize | 把值的首字母轉換成大寫,其他字母轉換成小寫 |
| lower | 把值轉換成小寫形式 |
| upper | 把值轉換成大寫形式 |
| title | 把值中每個單詞的首字母都轉換成大寫 |
| trim | 把值的首尾空格去掉 |
| striptags | 渲染之前把值中所有的HTML標簽都刪掉 |
| default() | 設定默認值,默認值作為引數傳入,別名為d |
| escape(s) | 轉義HTML文本,別名為e |
| first (seq) | 回傳序列的第一個元素 |
| last(seq) | 回傳序列的最后一個元素 |
| length(object) | 回傳變數的長度 |
| random(seq) | 回傳序列中的隨機元素 |
| max() | 回傳序列中的最大值 |
| min() | 回傳序列中的最小值 |
| unique() | 回傳序列中的不重復的值 |
| wordcount(s) | 計算單詞數量 |
| tojson() | 將變數值轉換為JSON格式 |
| truncate() | 截斷字串常用于顯示文章摘要,length引數設定截斷的長度 killwords 引數設定是否截斷單詞,end引數設定結尾的符號 |
【示例5】統計文章的長度,在 templates 檔案夾下新建 article.html 模板檔案,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>統計文章的長度</title>
</head>
<body>
<p style="color: red">全文共{{content|count_length}}字</p>
<p style="color: blue">全文共{{content | length()}}字</p>
<p>{{content}}</p>
</body>
</html>
templates_demo2.py 中代碼如下:
from flask import Flask, render_template
app = Flask(__name__)
# def count_length(arg): # # 實作一個可以求長度的函式
# return len(arg)
#
#
# app.add_template_filter(count_length, 'count_length')
@app.template_filter() # 使用裝飾器
def count_length(arg): # 實作一個可以求長度的函式
return len(arg)
@app.route('/')
def index():
content = """
Flask是一個使用Python撰寫的輕量級Web應用框架,基于Werkzeug WSGI工具箱和Jinja2模板引擎,Flask被稱為微框架,
因為它使用簡單的核心,用擴展增加其他功能,Flask沒有默認使用的資料庫、表單驗證工具等,然而,Flask保留了擴增的彈性,
可以用Flask擴展加入這些功能,例如:ORM、表單驗證工具、檔案上傳、各種開放式身份驗證技術等等,
"""
return render_template("article.html", content=content)
if __name__ == '__main__':
app.run(debug=True)
運行效果如下圖所示:

Jinja2 提供了多種控制結構,可用來改變模板的渲染流程,在模板中使用條件控制陳述句,代碼如下:
{% if user %}
hello, {{user}}!
{% else % }
hello, Paul!
{% endif %}
使用 for 回圈在模板中渲染一組元素,代碼如下:
<ul>
{% for comment in comments %}
<li>{{comment}}</li>
{% endfor %}
</ul>
Flask 框架有背景關系,Jinja2 模板也有背景關系,通常情況下,在渲染模板時呼叫 render_template() 函式向模板中傳入變數,此外,還可以使用 set 標簽在模板中定義變數,例如:
{% set navigation = [('/', 'home'), ('/about', 'About')] %}
也可以將一部分模板資料定義為變數,使用 set 和 endset 標簽宣告開始和結束,例如:
{% set navigation %}
<li><a href="/">首頁</a></li>
<li><a href="/about">關于我們</a></li>
{% endset %}
Flask 在模板背景關系中提供了一些內置全域變數,可以在模板中直接使用,內置全域變數及說明如下表所示:
| 屬性 | 說明 |
|---|---|
| config | 當前的配置物件 |
| request | 當前的請求物件,在已激活的請求環境下可用 |
| session | 當前的會話物件,在已激活的請求環境下可用 |
| g | 與請求系結的全域變數,在已激活的請求環境下可用 |
模板繼承類似于 Python 中類的繼承,Jinja2 允許定義一個基模板(也稱作父模板),把網頁上的導航欄、頁腳等通用內容放在基模板中,而每一個繼承基模板的子模板在被渲染時都會自動包含這些部分,使用這種方式可以避免在多個模板中撰寫重復的代碼,在 Jinja2 中,使用 extends 標簽實作子模板對父模板的繼承,父模板,代碼如下:
{% include '_nav.html' %}
{% block content %}
{% endblock %}
{% include '_footer.html' %}
說明:上述代碼中,使用 include 標簽引入了 _nav.html 導航欄和 _footer.html 底部資訊欄等 html 檔案,然后使用 block 標簽作為占位符,命名為 content,父模板中的占位符將被子模板中的名為 content 的 block 標簽的內容替換,
子模板,代碼如下:
{% extends 'base.html' %}
{% block content %}
使用block標簽替換父模板中的content內容,
{% endblock %}
在開發程序中,經常需要提示用戶當前操作成功或失敗的情況,例如,在添加商品資訊頁面,如果添加成功,應該提示 添加成功 資訊,否則提示 添加失敗 資訊,針對這種需求,Flask 提供了一個非常有用的 flash() 函式,它可以用來 閃現 需要顯示給用戶的訊息,flash() 函式語法格式如下:
flash(message,category)
引數說明:
- messag:訊息內容,
- category:訊息類型,用于將不同的訊息內容分類處理,
通常在視圖函式中呼叫 flash() 函式,傳入訊息內容即可 閃現 一條訊息,當然,它不是在用戶的瀏覽器彈出一條訊息,實際上,使用 flash() 函式發送的訊息會存盤在 Session 中,需要在模板中使用全域函 get_flashed_ messages() 獲取訊息串列,并將其顯示出來,
說明:通過 flash() 函式發送的訊息會存盤在 session 物件中,所以需要為程式設定密鑰,可以通過 app.secret_key 屬性或配置變數 SECRET_KEY 設定,
【示例6】注冊錯誤處理函式自定義錯誤頁面,404.html模板內容代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404頁面</title>
</head>
<body>
<img src="{{url_for('static',filename='images/404.png')}}" alt="404頁面">
</body>
</html>
error.py 中的代碼如下:
from flask import Flask, render_template
app = Flask(__name__)
# app.secret_key = "amoxiang" # 設定secret_key
@app.route('/')
def index():
return render_template("index.html")
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html')
if __name__ == '__main__':
app.run(debug=True) # 運行程式
運行效果如下圖所示:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/287892.html
標籤:其他
