requests.Request使用參數data傳值
-
當使用data傳值時,入參為object類型,在發送前,request將參數前置處理,在body中處理成格式為k1=v1&k2=v2 格式,content_type:application/x-www-form-urlencoded
import requests
import json
if __name__ == '__main__':
playload={
"person":json.dumps({
"name":"Milton",
"age": "18"
})
}
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
# resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
預處理格式如下:
content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}
這種情況下,服務端可以通過各個key將參數提取,如
person = request.POST.get("person")
。
-
注意:當如上字典多層嵌套時,只能解析到第一層,value值必須為字符串,否則會解析出錯,如下
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
}
}
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
# resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
預處理后,格式如下:
content_type:application/x-www-form-urlencoded
data body: person=name&person=age
這種情況,服務端解析,會解析不到預期的入參,請注意!!!
requests.Request使用參數json傳值
-
當request使用json傳值時,入參為json字符串,在發送前,request將參數前置處理,在body中處理成格式為json字符串,content_type:application/json
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
}
}
# resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
print(resp.text)
預處理格式如下:
content_type:application/json
json body: "{\"person\": {\"name\": \"Milton\", \"age\": \"18\"}}"
這種情況,服務端直接解析body,可以解析出合法json字符串,可以轉換成對象。如:
body=json.loads(request.body)
修改源碼,使得使用data傳參時,支持解析嵌套字典。
找到源碼位置:site-packages\requests\models.py
將_encode_params方法修改如下:
@staticmethod
def _encode_params(data):
"""Encode parameters in a piece of data.
Will successfully encode parameters when passed as a dict or a list of
2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
if parameters are supplied as a dict.
"""
if isinstance(data, (str, bytes)):
return data
elif hasattr(data, 'read'):
return data
elif hasattr(data, '__iter__'):
result = []
for k, vs in to_key_val_list(data):
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
vs = [vs]
for v in vs:
if v is not None:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
v.encode('utf-8') if isinstance(v, str) else v))
if isinstance(vs,dict):
result.append((k.encode('utf-8') if isinstance(k, str) else k,
complexjson.dumps(vs).encode('utf-8')))
return urlencode(result, doseq=True)
else:
return data
測試結果如下:
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
},
"address":"GZ"
}
requests.Request()
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
預處理參數如下:
content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}&address=GZ
通過以上修改源碼后,data參數已經可以支持嵌套多層字典!!!