使用FormData发布/补丁到django ArrayField

时间:2016-03-30 13:39:22

标签: javascript angularjs django django-rest-framework

因为我发布了一个文件,我必须使用$ http和一个FormData对象。当我发布一个带有字符串化数组的实例时,验证表明我没有发布整数。

我的模型看起来像这样:

class User(models.Model):
    work_week = ArrayField(models.IntegerField(), default=[0,1,2,3,4], size=7)

我的序列化器看起来像这样:

class UserSerializer(serializer.ModelSerializer):
    work_week = serializers.ListField(
       child=serializers.IntegerField(min_value=0, max_value=6)
    )

javascript帖子看起来像这样

let data = {
    work_week = [1,2,3];
}

let fd = new FormData();
for (let [key, val] of Object.entries(data)) {
   if (key === 'work_week') {
      val = JSON.stringify(val);
   }

   fd.append(key, val)
}

$http({
    url: full_url,
    method: this.method,
    data: fd,
    transformRequest: angular.identity,
    headers: {'Content-Type': undefined}
  })

我收到的错误消息是:

{work_week: ["A valid integer is required."]}

1 个答案:

答案 0 :(得分:0)

问题是你是字符串化work_week ...这会将该值转换为字符串“[1,2,3]”,而不是将其保留为正确的数组。但是,REST框架不处理序列化程序中从字符串到列表的转换。最简单的方法可能是在序列化程序中提供您自己的to_internal_values()

def to_internal_values(self, data):
    if isinstance(data['work_week'], str):
        data['work_week'] = json.loads(data['work_week'])
    do_any_validation_here()
    return data

当然,这是针对仅包含列表字段的序列化程序...您需要调整它以处理剩余的字段。您可以通过覆盖此字段的验证来为单个字段执行类似的操作,而不会影响序列化程序的其余部分:

def validate_work_week(self, value):
    if isinstance(value, str):
        value = json.loads(value)
    do_any_validation_here(value)
    return value

...但是我不记得在这个过程中是否会发生这种情况,以防止序列化程序拒绝该字符串。