【问题标题】:Error: too many values to unpack (expected 2) when raise error with serializers.ValidationError错误:当使用 serializers.ValidationError 引发错误时,需要解压的值太多(预期为 2)
【发布时间】:2020-04-20 06:24:09
【问题描述】:

我正在尝试通过覆盖to_internal_value 函数并使用ValidationError 显示错误消息来验证端点中的空字段,与以下answer 非常相似:

serializer.py

def to_internal_value(self, data):
    missing = []
    for k in ['comments']:
        try:
            if data[k] == '':
                missing.append(k)
        except Exception as e:
            missing.append(k)
        if len(missing):
            raise serializers.ValidationError("The following fields are required: %s" % ','.join(missing))
    return data

问题是我得到:Error: too many values to unpack (expected 2)raise serializers.ValidationError 指令被执行并且data 与cmets 字段为空(''):

(Pdb) data
<QueryDict: {'csrfmiddlewaretoken': ['<csrfmiddlewaretoken>'], 'comments': [''], 'user': ['']}>

甚至用一个简单的字符串进行测试:

raise serializers.ValidationError("The following fields are required: comments")

我收到同样的错误。在python控制台中,raise抛出错误:

>>> from rest_framework.serializers import ValidationError
>>> from rest_framework import serializers
>>> data={'comments': [''], 'user': ['']}
>>> missing=[]
>>> missing.append('comments')
>>> raise serializers.ValidationError("The following fields are required: %s" % ','.join(missing))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
rest_framework.exceptions.ValidationError: [ErrorDetail(string='The following fields are required: comments', code='invalid')]

我不得不使用ValueError() 而不是serializers.ValidationError(),它效果很好,但我想这不是建议的方式。

编辑 我正在使用:

Django==2.2.4
djangorestframework==3.10.3

然后我升级到:

Django==2.2.9
djangorestframework==3.11.0

结果相同。

【问题讨论】:

  • 我无法重现您的错误(解压缩的值太多)。 Raiseerror 仅返回 ValidationError: [ErrorDetail(string='The following fields are required: ', code='invalid')] django 3.0.1, djangoframework 3.11.0
  • 我升级到djangorestframework==3.11.0,但我收到了同样的错误。我更新了我的问题,添加了从 DRF Api 视图收到的 dict(数据)

标签: python django validation serialization django-rest-framework


【解决方案1】:

发生这种情况的原因是to_internal_value 收集所有验证错误并将它们作为字典传递,因此生成的400 响应可以包含所有发现的错误,而不仅仅是它遇到的第一个错误。这应该有效:

def to_internal_value(self, data):
    missing = []
    for k in ['comments']:
        try:
            if data[k] == '':
                missing.append(k)
        except Exception as e:
            missing.append(k)
        if len(missing):
            raise serializers.ValidationError(
                {"The following fields are required": missing}
            )
    return data

也就是说,如果您所做的只是验证是否存在某些内容,我建议您改为在序列化程序中的字段上声明 required=True,然后 DRF 将为您执行此检查。

【讨论】:

  • 我尝试过您的回答,但不幸的是我得到了相同的结果。我不能只使用required=True,因为该验证不会强制您发送可选的字段。最后,我认为根据您的回答,drf 验证器文档需要与该错误相关的更新。
【解决方案2】:

原因是ValidationError里面提出的run_validation应该用dict创建,例如:

ValidationError(','.join(missing): "These field are required")

【讨论】:

  • 这个答案是绝对正确的。修复进入 ValidationError(dict) 的数据类型后,我的问题就解决了。
猜你喜欢
  • 2019-01-13
  • 2019-12-28
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
相关资源
最近更新 更多