Django:从 QueryDict 读取 JSON 对象数组

Posted

技术标签:

【中文标题】Django:从 QueryDict 读取 JSON 对象数组【英文标题】:Django: Reading Array of JSON objects from QueryDict 【发布时间】:2012-04-19 14:35:06 【问题描述】:

如何通过来自 JS 和服务器端的 AJAX 调用传递复合 JSON 结构,在 python 中将其读取为“非常相似”的数据结构?

我知道可以使用 json 格式(simplejson 等),但不知何故,我觉得 QueryDict 本身格式错误或重新格式化?

例子:

当通过 AJAX 将 JSON 对象数组 ["id": 1,"id": 2,"id": 3] 传递给 Django 视图时,QueryDict 的格式为:

POST:<QueryDict: u'json_data[0][id]': [u'1'], u'type': [u'clone'], 
u'csrfmiddlewaretoken': [u'69bb3c434ced31ab301ede04bf491ec0'], 
u'json_data[1][id]': [u'2'], u'json_data[2][id]': [u'3']>

我什至如何遍历 json_data?

我想得到这样的东西:

POST:<QueryDict: u'json_data': [u'id': [u'1'], u'id': [u'2'], u'id': [u'3']],
u'csrfmiddlewaretoken': [u'69bb3c434ced31ab301ede04bf491ec0'], u'type': [u'clone']>

这样我就可以将 QueryDict 作为字典访问并将 json_data 作为列表检索并按特定顺序处理它:也许只是按顺序列表顺序遍历它们。 类似的东西:

ret = request.POST
for item in ret['json_data']:
    process(item['id'])

事实上,进入 process() 的值可能是另一个键值对字典,而不仅仅是一个数字(1、2、3 等)

Javascript:

var test = ["id": 1,"id": 2,"id": 3];
$.post(
    "/insert_tc",
    
      json_data: test,
      "type": 'clone',
      "csrfmiddlewaretoken": $csrf_token
    ,  
    function(json) 
        //CALLBACK
    ,
    "json"
);  

views.py:

def insert_tc(request):
    if request.method == 'POST':       
    ret = request.POST
    type = ret['type']
    list = ret.getlist(ret)

但列表返回空 []

我尝试了 simplejson 转储、加载、项目、获取方法,但都没有帮助。

我什至尝试过 jQuery.param(obj, true),但这不是我想要的(虽然有点接近)。

有没有不同/更好的方式来通过 AJAX 来回传递复合数据结构 Django JS?

【问题讨论】:

肯定有问题,因为发布的代码肯定不会给出 QueryDict 结果。请问你能发布输出的确切代码吗? 恐怕JS代码是准确的。我从views.py复制粘贴了JS sn-p和打印请求的输出,并带有较小的格式。 'test' 是我要传递的对象数组。 对不起,我的错误。请参阅下面的答案。 【参考方案1】:

您应该使用 JSON.stringify() 对 JSON 进行字符串化。这会将 JSON 对象转换为字符串格式,以便在另一端正确解析。另一方面,您将需要使用 json.loads() 来“取消字符串化”对象。

javascript

var test = ["id": 1,"id": 2,"id": 3];
$.post(
    "/insert_tc",
    
      json_data: JSON.stringify(test),
      "type": 'clone',
      "csrfmiddlewaretoken": $csrf_token
    ,  
    function(json) 
        //CALLBACK
    ,
    "json"
);  

查看

import json
def insert_tc(request):
    if request.method == 'POST':       
        ret = request.POST
        type = ret['type']
        list = json.loads(ret['json_data'])

【讨论】:

谢谢!尽管 Daniel 的回答很及时并且确实帮助我克服了障碍,但由于 JSON.stringify() 更干净地完成了这项工作,因此我将其转换为公认的答案。 JSON 在旧版本的 IE 中似乎不可用。以为有人想知道。不过,这似乎仍然是最好的方法。【参考方案2】:

这实际上是 jQuery,而不是 Django,很奇怪。您的 test 变量不包含 JSON,而是实际的 JS 对象。 jQuery,出于自己最熟悉的原因,在发布之前将其解析为一些非常奇怪的格式,因此您得到了结果。如果你这样做了(注意整个事情的引号):

var test = '["id": 1,"id": 2,"id": 3]';

您会发现您获得的 QueryDict 非常接近您的预期:您唯一需要做的就是致电 json.loads(ret['json_data'])

还有一些我无法理解的原因。 jQuery 不包含将对象数组转换为 JSON 的任何功能。您需要为此找到一个插件或单独的库。

【讨论】:

我对人性的信仰已经恢复。谢谢!我几乎让它工作了。很高兴知道这种行为背后的原因(也许是一些文章/链接?)

以上是关于Django:从 QueryDict 读取 JSON 对象数组的主要内容,如果未能解决你的问题,请参考以下文章

django QueryDict对象

django基础知识之QueryDict对象:

在 Django 中处理 ajax json 对象 - 'QueryDict' 对象没有属性 'read' 错误

django.http.request中QueryDict 对象

django-QueryDict 对象

Django中QueryDict