django中ajax post数据时request.POST获取数组问题

1、前言

最近在使用django开发web页面时,使用ajax的post参数中带有数组,然后在 request.POST 里获取的数组时,数组变成了一个元组!!!官方给出的通过 request.POST.getlist('key')来获取也是很鸡肉!那要怎么解决呢?

2、问题

问题是这样,在前端js的post请求参数带有数组或字典:

    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,获取数组就变成这样:

如果是这样写:

    if request.method == 'POST':
        array = request.POST['array']
        dict = request.POST['dict']

直接是报错:

raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'array'

所以我们要看看 request.POST 到底是什么类型,内容又是什么???

request.POST:
<QueryDict: {'account': ['account'], 'password': ['password'], 'array[]': ['1', '2', '3'], 'dict[k1]': ['v1'], 'dict[k2]': ['v2']}>

QueryDict ???字典!!!

从前端传入的数组,变成了字典,问题有三个:

  • array 变成 array[]
  • [1, 2, 3] 变成 ['1', '2', '3']
  • dict 变成 dict[k1]dict[k1]

其实,这个不是bug!!!

这是一个 django 自定义的类似字典的类,用来处理同一个键带多个值的情况。 python 原始的字典中,当一个键出现多个值的时候会发生冲突,只保留最后一个值。而在 HTML 表单中,通常会发生一个键有多个值的情况。

例如:

 query_string 需要一个字符串 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] 只取到容器的最后一个值:

20180905-request.POST-get.png

getlist(key[]) 数组可以拿到字符串数组,但是字典就只能一个一个拿了!

20180905-request.POST-getlist.png

3、解决方法

  • 方法一

在前端的body参数变成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"}}': ['']}>

全部参数作为key的字典,显示不符合要求,并且导致处理复杂起来。

  • 方法二
    子级变成json字符串:
    var body = {
        'account': account,
        'password': password,
        'array': JSON.stringify([1, 2, 3]),
        'dict': JSON.stringify({'k1': 'v1', 'k2': 'v2'})
    };

得到的结果:

<QueryDict: {'account': ['account'], 'password': ['password'], 'array': ['[1,2,3]'], 'dict': ['{"k1":"v1","k2":"v2"}']}>

数组和字典的全部值作为value,并且是string类型,显示不符合要求,并且导致处理复杂起来。

  • 方法三
    其实,我们知道后端为了多个相同key存在,所以才这样处理,那么我们可以这样考虑,让数据和字典不在是数组和字典,后端在还原不就可以啦!
    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字符串形式,然后后端按规则还原:

<QueryDict: {'account': ['account'], 'password': ['password'], 'array': ['1[1,2,3]'], 'dict': ['1{"k1":"v1","k2":"v2"}']}>

按规则还原:

    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

这样拿也许不是好办法,但是当你数组或字典数据非常多时,也就这样啦,当然,也可以json字符串后加密,这样后端也不能解析,如果需要,大家也可以这样做啊~

总结

在处理这些数据时,可能是为了方便而方便,有时候只有清楚知道原因,才能更好的处理,上面的方法确实不是好方法,有时候还是按规则来处理更好,一个人开发还好,如果是多人,那将来可能会留下坑啊。

参考


  • 如有疑问,欢迎在评论区一起讨论!
  • 如有不正确的地方,欢迎指导!


注:本文首发于 iHTCboy's blog,如若转载,请注来源

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容