如何序列化发布到django后端的数组

时间:2017-01-23 20:43:35

标签: jquery python django serialization django-serializer

我正在尝试序列化来自表单的数组。该数组如下所示:

some_id: 12
array1[]:1
array1[]:2
array2[]:5
array2[]:6

或者,当它到达request.POST

<QueryDict: {
    'array1[]': ['1', '2'], 
    'array2[]': ['5', '6'], ...

现在我让序列化程序为简单的id some_id = serializers.IntegerField()工作,这很棒。我已经在没有数组的情况下进行了测试,一切都按预期工作。

对于数组,我以为我找到了这个序列化字段:listfield
 我尝试了以下实现:

array1 = serializers.ListField(
    child=serializers.IntegerField(min_value=1)
)

这看起来像手册说它是如何工作的,但它似乎只给我以下错误:

  

/ api / myendpoint /上的TypeError   'int'对象不可迭代

我不确定我哪里出错了,也许我走错了路(真的不是Django家伙:)),但我确定这是一个小错误。

那么如何序列化已发布的数组(或者我应该将其称为Dict?)

完整的跟踪似乎并没有包含任何奇怪的内容,但我保持其可用on pastebin

使用此jquery代码发布数据:

var mydata = {
    array1: [1,2],
    array2: [5,6],
    some_id: 12
};

$.ajax({
    url: "http://domain.com//api/myendpoint/",
    dataType: "json",
    data: mydata,
    method: "POST"
})

我正在使用:

  • Django 1.10.2
  • djangorestframework 3.5.2
  • jquery 2.1.4

2 个答案:

答案 0 :(得分:2)

长话短说:我已将此添加到我的javascript:

jQuery.ajaxSettings.traditional = true;

现在它的效果就像你期望的那样

短篇小说:

最大的问题是“简单”的帖子并不像我想象的那么简单。从这个问题来看,这就是jQuery发布的内容:

some_id: 12
array1[]:1
array1[]:2
array2[]:5
array2[]:6

从前端发送并在后端预期的对象包含名为array1array2的属性,但发送的内容实际上是array1[]array2[] 。虽然Daniel van Flymen的解决方案可能会使用这些属性,但我一直在考虑修复这些括号。

this rather old jquery topic我发现jQuery为phpruby等语言添加了这些,但是我发现:python不喜欢它

添加jQuery.ajaxSettings.traditional = true;后,标题现在如下所示:

some_id: 12
array1:1
array1:2
array2:5
array2:6

这就是序列化程序按预期理解的内容。

答案 1 :(得分:1)

您的值不会作为数组发送。它们作为单独的密钥发送。

如果您打算将数组的反序列反序列化,那么您可以覆盖序列化程序上的to_internal_value()方法:

class CustomSerializer(serializers.Serializer):
    my_array = serializers.ListField(
        child=serializers.IntegerField(min_value=1)
    )

    def to_internal_value(self, data):
        my_array = []
        for key, value in data.items():
            if "array[]" in key:
                my_array.append(value)

        # Perform some validation on your array
        for item in array:
            if item > 10:
                raise ValidationError(
                    {
                        'my_array': "A number was higher than 10."
                    }
                )

        # Return the validated values    
        return {
            'my_array': my_array
        }

to_internal_value()方法负责反序列化数据。希望这能指出你正确的方向。 请务必查看to_internal_value()上的documentation中的示例。