1、前言
最近在使用django開(kāi)發(fā)web頁(yè)面時(shí)乍楚,使用ajax的post參數(shù)中帶有數(shù)組当编,然后在 request.POST
里獲取的數(shù)組時(shí),數(shù)組變成了一個(gè)元組4逗馈!拧篮!官方給出的通過(guò) request.POST.getlist('key')
來(lái)獲取也是很雞肉词渤!那要怎么解決呢?
2串绩、問(wèn)題
問(wèn)題是這樣缺虐,在前端js的post請(qǐng)求參數(shù)帶有數(shù)組或字典:
var body = {
'account': account,
'password': password,
'array': [1, 2, 3],
'dict': {'k1': 'v1', 'k2': 'v2'}
};
$.ajax({
url: url,
type: "POST",
data: body,
...
...
});
在django后python解析request.POST,獲取數(shù)組就變成這樣:
如果是這樣寫(xiě):
if request.method == 'POST':
array = request.POST['array']
dict = request.POST['dict']
直接是報(bào)錯(cuò):
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'array'
所以我們要看看 request.POST
到底是什么類型礁凡,內(nèi)容又是什么高氮??顷牌?
request.POST:
<QueryDict: {'account': ['account'], 'password': ['password'], 'array[]': ['1', '2', '3'], 'dict[k1]': ['v1'], 'dict[k2]': ['v2']}>
QueryDict
剪芍??窟蓝?字典W锕!!
從前端傳入的數(shù)組状共,變成了字典套耕,問(wèn)題有三個(gè):
-
array
變成array[]
鍵 -
[1, 2, 3]
變成['1', '2', '3']
-
dict
變成dict[k1]
、dict[k1]
其實(shí)峡继,這個(gè)不是bug7肱邸!碾牌!
這是一個(gè) django 自定義的類似字典的類康愤,用來(lái)處理同一個(gè)鍵帶多個(gè)值的情況。 python 原始的字典中小染,當(dāng)一個(gè)鍵出現(xiàn)多個(gè)值的時(shí)候會(huì)發(fā)生沖突翘瓮,只保留最后一個(gè)值。而在 HTML 表單中裤翩,通常會(huì)發(fā)生一個(gè)鍵有多個(gè)值的情況资盅。
例如:
query_string 需要一個(gè)字符串 a=1&a=2&c=3,例如:
>>> QueryDict('a=1&a=2&c=3')
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>
那么怎么取值呢踊赠?
按照getlist(key)
拿不到:
用 [key]
只取到容器的最后一個(gè)值:
用 getlist(key[])
數(shù)組可以拿到字符串?dāng)?shù)組呵扛,但是字典就只能一個(gè)一個(gè)拿了!
3筐带、解決方法
- 方法一
在前端的body參數(shù)變成json字符串:
var body = JSON.stringify({
'account': account,
'password': password,
'array': [1, 2, 3],
'dict': {'k1': 'v1', 'k2': 'v2'}
})
但在后端得到的是這樣:
<QueryDict: {'{"account":"account","password":"password","array":[1,2,3],"dict":{"k1":"v1","k2":"v2"}}': ['']}>
全部參數(shù)作為key的字典今穿,顯示不符合要求,并且導(dǎo)致處理復(fù)雜起來(lái)伦籍。
- 方法二
子級(jí)變成json字符串:
var body = {
'account': account,
'password': password,
'array': JSON.stringify([1, 2, 3]),
'dict': JSON.stringify({'k1': 'v1', 'k2': 'v2'})
};
得到的結(jié)果:
<QueryDict: {'account': ['account'], 'password': ['password'], 'array': ['[1,2,3]'], 'dict': ['{"k1":"v1","k2":"v2"}']}>
數(shù)組和字典的全部值作為value蓝晒,并且是string類型,顯示不符合要求帖鸦,并且導(dǎo)致處理復(fù)雜起來(lái)芝薇。
- 方法三
其實(shí),我們知道后端為了多個(gè)相同key存在作儿,所以才這樣處理洛二,那么我們可以這樣考慮,讓數(shù)據(jù)和字典不在是數(shù)組和字典攻锰,后端在還原不就可以啦晾嘶!
var body = {
'account': account,
'password': password,
'array': '1' + JSON.stringify([1, 2, 3]),
'dict': '1' + JSON.stringify({'k1': 'v1', 'k2': 'v2'})
};
讓 'array'、'dict' 變成 ‘1’ + json字符串形式娶吞,然后后端按規(guī)則還原:
<QueryDict: {'account': ['account'], 'password': ['password'], 'array': ['1[1,2,3]'], 'dict': ['1{"k1":"v1","k2":"v2"}']}>
按規(guī)則還原:
array = request.POST['array']
dict = request.POST['dict']
array_list = json.loads(array[1:])
dict_list = json.loads(dict[1:])
這樣拿也許不是好辦法垒迂,但是當(dāng)你數(shù)組或字典數(shù)據(jù)非常多時(shí),也就這樣啦妒蛇,當(dāng)然娇斑,也可以json字符串后加密策添,這樣后端也不能解析,如果需要毫缆,大家也可以這樣做啊~
總結(jié)
在處理這些數(shù)據(jù)時(shí)唯竹,可能是為了方便而方便,有時(shí)候只有清楚知道原因苦丁,才能更好的處理浸颓,上面的方法確實(shí)不是好方法
,有時(shí)候還是按規(guī)則來(lái)處理更好旺拉,一個(gè)人開(kāi)發(fā)還好产上,如果是多人,那將來(lái)可能會(huì)留下坑啊蛾狗。
參考
- 關(guān)于ajax post 數(shù)據(jù)時(shí)django中request.body與request.POST問(wèn)題 - 簡(jiǎn)書(shū)
- django-QueryDict 對(duì)象 - scolia - 博客園
- Request and response objects | Django documentation | Django
- django中同通過(guò)getlist() 接收頁(yè)面form的post數(shù)組 - ccorz - 博客園
- 如有疑問(wèn)晋涣,歡迎在評(píng)論區(qū)一起討論!
- 如有不正確的地方沉桌,歡迎指導(dǎo)谢鹊!
注:本文首發(fā)于 iHTCboy's blog,如若轉(zhuǎn)載留凭,請(qǐng)注來(lái)源