1. 程式人生 > 其它 >Flask(7)- request 物件

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 等於http://localhost/query?userId=123,request物件中與 URL 引數相關的屬性如下

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

獲取 url 請求引數的栗子

程式碼

#!usr/bin/env python
# -*- coding:utf-8 _*-
""" # author: 小菠蘿測試筆記 # blog: https://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:  https://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:  https://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 的資料