django中ajax post數(shù)據(jù)時(shí)request.POST獲取數(shù)組問(wèn)題

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) 拿不到:

20180905-request.POST-getlist-key.png

[key] 只取到容器的最后一個(gè)值:

20180905-request.POST-get.png

getlist(key[]) 數(shù)組可以拿到字符串?dāng)?shù)組呵扛,但是字典就只能一個(gè)一個(gè)拿了!

20180905-request.POST-getlist.png

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:])
20180905-request.POST-irregular.png

這樣拿也許不是好辦法垒迂,但是當(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ì)留下坑啊蛾狗。

參考


  • 如有疑問(wèn)晋涣,歡迎在評(píng)論區(qū)一起討論!
  • 如有不正確的地方沉桌,歡迎指導(dǎo)谢鹊!


注:本文首發(fā)于 iHTCboy's blog,如若轉(zhuǎn)載留凭,請(qǐng)注來(lái)源

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佃扼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蔼夜,更是在濱河造成了極大的恐慌兼耀,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件求冷,死亡現(xiàn)場(chǎng)離奇詭異瘤运,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)匠题,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門拯坟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人梧躺,你說(shuō)我怎么就攤上這事似谁“列澹” “怎么了掠哥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秃诵。 經(jīng)常有香客問(wèn)我续搀,道長(zhǎng),這世上最難降的妖魔是什么菠净? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任禁舷,我火速辦了婚禮彪杉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牵咙。我一直安慰自己派近,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布洁桌。 她就那樣靜靜地躺著渴丸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪另凌。 梳的紋絲不亂的頭發(fā)上谱轨,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音吠谢,去河邊找鬼土童。 笑死,一個(gè)胖子當(dāng)著我的面吹牛工坊,可吹牛的內(nèi)容都是我干的献汗。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼栅组,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雀瓢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起玉掸,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刃麸,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后司浪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體泊业,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年啊易,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吁伺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡租谈,死狀恐怖篮奄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情割去,我是刑警寧澤窟却,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站呻逆,受9級(jí)特大地震影響夸赫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咖城,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一茬腿、第九天 我趴在偏房一處隱蔽的房頂上張望呼奢。 院中可真熱鬧,春花似錦切平、人聲如沸握础。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)弓候。三九已至,卻和暖如春他匪,著一層夾襖步出監(jiān)牢的瞬間菇存,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工邦蜜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留依鸥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓悼沈,卻偏偏與公主長(zhǎng)得像贱迟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子絮供,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容