Flask(7)- request 對象

Flask 中很重要的 request 對象

  • 瀏覽器訪問服務端時,向服務端發送請求
  • Flask 程式使用 request 對象描述請求資訊
  • 當你想獲取請求體、請求參數、請求頭數據的時候,就需要靠 request 對象了
  • 這一篇會用結果驅動源碼解析的方式來講解

 

真實使用場景

瀏覽器訪問服務端,需要將相應的數據發送給服務端,可能有如下場景:

  1. 通過 URL 參數進行查詢,瀏覽器需要將查詢參數發送給服務端
  2. 提交表單 form 進行查詢,瀏覽器需要將表單 form 中的欄位發送給服務端
  3. 上傳文件,瀏覽器需要將文件發送給服務端
  4. 通過 JSON 格式的請求體進行請求,一般是 post 請求

服務端收到將客戶端發送的數據後,封裝形成一個請求對象,在 Flask 中,請求對象是一個模組變數 flask.request

 

request 包含的常用屬性 

屬性 說明
method 當前的請求方法
form 表單參數及其值的字典對象
args 查詢字元串的字典對象
values 包含所有數據的字典對象
json 如果 mimetype 是 application/json,這個參數將會解析 json 數據,如果不是則返回 None
headers http 協議 請求頭
cookies cookie 名稱和值的字典對象
files 與上傳文件有關的數據

form、args、values、json 都是獲取 http 請求的請求數據的屬性,只不過請求體類型不同

 

還記得之前講 url 組成的時候,request 對象也能獲取 url 相關參數嗎,複習下

 

request 獲取 url 組成的常用屬性

假設 URL 等於 //localhost/query?userId=123,request 對象中與 URL 參數相關的屬性如下

屬性 說明
url //localhost/query?userId=123
base_url //localhost/query
host localhost
host_url //localhost/
path /query
full_path /query?userId=123

 

獲取 url 請求參數的栗子

程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog:  //www.cnblogs.com/poloyy/
# time: 2021/7/11 11:13 上午
# file: 5_request.py
"""

from flask import Flask, request

app = Flask(__name__)


@app.route('/query')
def query():
    return {"name": request.args['name'], "age": request.args['age']}


@app.route('/query2')
def query2():
    print('args =', request.args)
    print('form =', request.form)
    return "form"


@app.route('/query3')
def query3():
    print('args =', request.args)
    print('json =', request.json)
    return "json"


@app.route('/query4')
def query4():
    return {"name": request.values['name'], "age": request.values['age']}


if __name__ == '__main__':
    app.run(debug=True)
  • 下面我會用 postman 統一通過 params,就是 url 請求參數傳數據
  • 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑

 

postman 發起請求的結果

/query

 

/query2

控制台輸出

args = ImmutableMultiDict([('name', 'zhangsan'), ('age', '13')])
form = ImmutableMultiDict([])

用 form 屬性的話得到是一個空字典哦

 

/query3

控制台輸出

args = ImmutableMultiDict([('name', 'zhangsan'), ('age', '13')])
json = None 

用 json 屬性的話得到是一個 None 哦,所以無論如何都不要用 json 獲取 url 請求參數喲!

 

/query4

可以看到 values 屬性也能拿到 url 請求參數哦

 

獲取表單參數的栗子

程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog:  //www.cnblogs.com/poloyy/
# time: 2021/7/11 1:47 下午
# file: 5_request_form.py
"""

from flask import Flask, request

app = Flask(__name__)

@app.route('/addUser', methods=['POST'])
def check_login():
    return {"name": request.form['name'], "age": request.form['age']}


@app.route('/addUser2', methods=['POST'])
def check_login2():
    print('form =', request.form)
    print('args =', request.args)
    return "good"


@app.route('/addUser3', methods=['POST'])
def check_login3():
    print('form =', request.form)
    print('json =', request.json)
    return "good"


@app.route('/addUser4', methods=['POST'])
def check_login4():
    return {"name": request.values['name'], "age": request.values['age']}


if __name__ == '__main__':
    app.run(debug=True)
  • 下面我會用 postman 統一通過 form-data,就是表單格式來傳數據
  • 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑

 

postman 發起請求的結果

/addUser

 

/addUser2

控制台輸出

form = ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])
args = ImmutableMultiDict([])

用 args 屬性的話得到是一個空字典哦

 

/addUser3

控制台輸出

form = ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])
json = None

用 json 屬性的話得到是一個 None 哦,所以無論如何都不要用 json 獲取 form-data 喲!

 

/addUser4

可以看到 values 屬性也能拿到 form 表單提交的數據哦

 

獲取 Json 數據的栗子

程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog:  //www.cnblogs.com/poloyy/
# time: 2021/7/11 1:47 下午
# file: 5_request_form.py
"""

from flask import Flask, request

app = Flask(__name__)


@app.route('/addJson', methods=['POST'])
def check_login():
    return {"name": request.json['name'], "age": request.json['age']}


@app.route('/addJson2', methods=['POST'])
def check_login2():
    print('json =', request.json)
    print('args =', request.args)
    return "good"


@app.route('/addJson3', methods=['POST'])
def check_login3():
    print('json =', request.json)
    print('form =', request.form)
    return "good"


@app.route('/addJson4', methods=['POST'])
def check_login4():
    print('json =', request.json, type(request.json))
    print('values =', request.values)
    return {"name": request.json['name'], "age": request.json['age']}
if __name__ == '__main__': app.run(debug=True)
  • 下面我會用 postman 統一通過 raw-json,就是 Json 格式的請求體來傳數據
  • 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑

 

postman 發起請求的結果

/addJson

 

/addJson2

json = {'age': '12', 'name': 'poloyy'}
args = ImmutableMultiDict([])

用 args 屬性的話得到是一個空字典哦 

 

/addJson3

json = {'age': '12', 'name': 'poloyy'}
form = ImmutableMultiDict([])

 用 form 屬性的話得到是一個空字典哦

 

/addJson4

這裡要注意的是,當你的請求體是 Json 時,是不能通過 values 來獲取請求數據哦!!

最後來看看 request.json 會返回什麼吧

json = {'age': '12', 'name': 'poloyy'} <class 'dict'>

request.json 拿到的就是 Json 格式的請求體,並且自動轉換成字典了哦!

 

為什麼 requests.values 能獲取 form、args 的數據,但是拿不到 json 的數據呢?

request.values 源碼

  • 能看到,它本質就是獲取 args、form 的數據,但不包含 json 數據
  • 但是這裡有個重點,只有你的請求方法不為 GET 的時候,發送 form 表單數據才能通過 request.values 拿到請求數據
  • 來試試是不是真的這樣

 

程式碼

@app.route('/query4', methods=["GET", "POST"])
def query4():
    print(request.form)
    print(request.args)
    print(request.values)
    return {"name": request.values['name'], "age": request.values['age']}

 

postman 發起 GET 請求,form-data 傳數據

直接報錯,找不到對應的 name key,因為 request.values 是空的

 

控制台輸出

ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])
CombinedMultiDict([ImmutableMultiDict([])])
ImmutableMultiDict([])

很明顯,request.form 是能拿到數據的,但是 request.value 是拿不到數據哦

 

postman 發起 POST 請求,form-data 傳數據

這次就能正常顯示返回值啦

 

控制台輸出

ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])
ImmutableMultiDict([])
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])])

看源碼應該知道,當非 GET 請求的時候傳遞表單數據,request.values 也能獲取得到 request.form 的數據