Flask 學習筆記
一、URL 與 視圖
1.1、URL 與 函數的映射
從之前的 helloworld.py 文件中,我們已經看到,一個 URL 要與執行函數進行映射,使用的是 @app.route 裝飾器
。裝飾器中,可以指定 URL 的規則來進行更加詳細的映射,比如現在要映射一個文章詳情的 URL,文章詳情的 URL 是 /list/id/
,id
有可能爲 1、2、3…,那麼可以通過以下方式:
@app.route('/')
def hello_word():
return 'Hello World!'
@app.route('/list/')
def lis_word():
return 'list 頁面'
@app.route('/list/<id>/')
# @app.route('/list/<int:id>/')
def lis(id):
# 訪問 http://127.0.0.1:5000/list/66s
# 訪問 http://127.0.0.1:5000/list/66
return f'這是第 {id} 個頁面'
其中,尖括號是固定寫法,語法爲,variable 默認的數據類型是 字符串。如果需要指定類型,則要寫成 converter:variable
,其中 converter 就是類型名稱(如 int),可以有以下幾種:
-
string
:默認的數據類型,接受沒有任何斜槓/的字符串。 -
int
:整形。可寫成/list/<int:id>/
-
float
:浮點型。 -
path
:和 string 類似,但是可以傳遞斜槓/。 -
uuid
:uuid 類型的字符串。 -
any
:可以指定多種路徑。
any 指定多個路徑
@app.route('/<any(article,blog):url_path>/')
def item(url_path):
# 訪問 http://127.0.0.1:5000/article
# 訪問 http://127.0.0.1:5000/blog
return url_path
如果不想定製子路徑來傳遞參數,也可以通過傳統的 ?=
的形式來傳遞參數,例如:/article?id=xxx
,這種情況下,可以通過 request.args.get('id')
來獲取 id
的值。如果是 post 方法,則可以通過 request.form.get('id')
來進行獲取。
from flask import request
@app.route('/wd')
def req():
return request.args.get("name")
二、構造 URL
一般我們通過一個 URL 就可以執行到某一個函數。如果反過來,我們知道一個函數,怎麼去獲得這個 URL 呢 ?url_for()
函數就可以幫我們實現這個功能。url_for()
函數接收兩個及以上的參數,他接收函數名作爲第一個參數,接收對應 URL 規則的命名參數,如果還出現其他的參數,則會添加到 URL 的後面作爲查詢參數。
通過構建 URL 的方式而不是選擇直接在代碼中拼 URL 的原因有兩點:
- 將來如果修改了 URL,但沒有修改該 URL 對應的函數名,就不用到處去替換 URL 了。
- url_for() 函數會轉義一些特殊字符和 unicode 字符串,這些事情 url_for 會自動的幫我們搞定。
from flask import Flask, url_for
app = Flask(__name__)
@app.route("/lis/<aid>/")
def lis(aid):
return f"article list {aid}"
@app.route('/')
def index():
name = url_for("lis", aid=5, name="admin")
print(name) # 控制檯打印出 /lis/5/?name=admin
return "Hello World!"
if __name__ == '__main__':
app.run(debug=True)
三、指定 HTTP 方法
在 @app.route()
中可以傳入一個關鍵字參數 methods
來指定方法支持的 HTTP 方法,默認情況下,只能使用 GET 請求。
# 沒有 methods 參數默認只接收 get 請求
# 有 methods 參數後, 只接收參數所包含的請求
@app.route("/login/", methods=['GET', 'POST'])
def login():
# print(type(request.args))
# GET請求接受參數
print(request.args.get('username'))
# POST請求接受參數
print(request.form.get("name"))
return "login"
四、頁面跳轉與重定向
重定向分爲永久性重定向和暫時性重定向,在頁面上體現的操作就是瀏覽器會從一個頁面自動跳轉到另外一個頁面。比如用戶訪問了一個需要權限的頁面,但是該用戶當前並沒有登錄,因此我們應該給他重定向到登錄頁面。
-
永久性重定向: http 的狀態碼是
301
。多用於舊網址被廢棄了要轉到一個新的網址確保用戶的訪問。最經典的就是京東網站,你輸入www.jingdong.com
的時候,會被重定向到www.jd.com
因爲www.jingdong.com
這個網址已經被廢棄了,被改成jd.com
,所以這種情況下應該用永久重定向。 -
暫時性重定向: http 的狀態碼是
302
。表示頁面的暫時性跳轉。比如訪問一個需要權限的網址,如果當前用戶沒有登錄,應該重定向到登錄頁面,這種情況下,應該用暫時性重定向。
在 Flask 中,重定向是通過 flask.redirect(location, code=302)
這個函數來實現的。其中 location
表示需要重定向到的 URL,應該配合之前的 url _for()
函數來使用,code
表示採用哪一個重定向,默認是 302 暫時性重定向,也可以修改成 301 來實現永久性重定向。
from flask import Flask, ur1_ for, redirect
Flask(__name__)
@app.route('/login/', methods=['GET', 'POST'])
def login():
return 'login page'
@app.route('/profile/', methods=['GET', 'POST'])
def profile():
name = request.args.get('name')
if not name:
return redirect(url_for('login'))
else:
return name
五、響應
視圖函數可以返回 string, dict, tuple, Response instance, WSGI callable
等類型的值,但是不能返回列表型數據。
from flask import Response, make_response
@app.route("/about/")
def about():
# # 返回字符串
# return "666"
# # 不能返回列表
# return ['a', 'b']
# # 返回字典
# return {'name': 'li', 'age': '18', 'sex': 1}
# # 返回元組, 但默認返回第一個
# return ('name', 'li')
# return ('name', 'li')[1]
# # 一般也不會像上面這個返回元組, 而是如下
# return 'name', 200
# # 返回 Response 對象, 參數: 顯示的字符串、狀態碼、類型
# # 這個返回其實相當於返回字符串
# return Response("haha", status=200, mimetype="text/html")
# 使用 make_response() 創建 Response 對象
# 可以設置額外的數據, 如設置 cookie, header 信息
return make_response("hello")