错误:在使用序列化程序.ValidationError 引发错误时要解压的值太多(预期为 2)

Man*_*ero 5 python django validation serialization django-rest-framework

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

序列化程序.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
Run Code Online (Sandbox Code Playgroud)

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

(Pdb) data
<QueryDict: {'csrfmiddlewaretoken': ['<csrfmiddlewaretoken>'], 'comments': [''], 'user': ['']}>
Run Code Online (Sandbox Code Playgroud)

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

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')]
Run Code Online (Sandbox Code Playgroud)

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

编辑 我正在使用:

Django==2.2.4
djangorestframework==3.10.3
Run Code Online (Sandbox Code Playgroud)

然后我升级到:

Django==2.2.9
djangorestframework==3.11.0
Run Code Online (Sandbox Code Playgroud)

结果相同。

Cha*_*ays 5

发生这种情况的原因是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
Run Code Online (Sandbox Code Playgroud)

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


小智 5

原因是ValidationError里面raisedrun_validation应该用dict创建,例如:

ValidationError(','.join(missing): "These field are required")
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是绝对正确的。修复进入 ValidationError(dict) 的数据类型后,我的问题得到了解决。 (3认同)