表单 ValidationError 和错误代码

Posted

技术标签:

【中文标题】表单 ValidationError 和错误代码【英文标题】:Forms ValidationError and error code 【发布时间】:2013-09-17 20:33:37 【问题描述】:

在 Django 文档中https://docs.djangoproject.com/en/dev/ref/forms/validation/#raising-validationerror 说,在引发 ValidationError 异常的同时提供错误代码是一种好习惯。

# Good
ValidationError(_('Invalid value'), code='invalid')

# Bad
ValidationError(_('Invalid value'))

我的应用程序中有 API,我正在使用表单来验证输入数据。 如果表单无效,我想获取这些错误代码(不是错误消息)。

于是我查看了BaseForm的_clean_fields方法的源码:https://github.com/django/django/blob/master/django/forms/forms.py#L278

except ValidationError as e:
    self._errors[name] = self.error_class(e.messages)
    if name in self.cleaned_data:
        del self.cleaned_data[name]

据我了解,此参数(self.code)未在任何地方传递,并且在表单验证后无法获取。

谁能解释一下使用这个错误代码的目的是什么?

【问题讨论】:

似乎这是一个新增功能 - 请参阅“1.6 中的新功能”的注释,它甚至还没有发布 - 所以它可能还没有在所有地方完全实现。 这个字段也出现在 1.5 中。看起来你是对的,它会在未来的版本中使用。 【参考方案1】:

在 Django 1.7 中,您现在可以从表单访问原始错误数据。您可以在ErrorListErrorDict 上调用as_data() 方法。例如:my_form.errors.as_data()。这基本上为您提供了原始的 ValidationError 对象而不是消息本身。从这里您可以访问.code 属性,例如:my_form.errors["__all__"].as_data()[0].code

您还可以序列化表单错误,非常适合 API:

>>> print(form.errors.as_json())
"__all__": [
    "message": "Your account has not been activated.", "code": "inactive"
]

【讨论】:

从 django 1.10 开始,访问代码的正确方法是 form.errors.as_data()['field_name'][0].code【参考方案2】:

看看 django src 中的 ValidationError 定义,它被用作传递附加标识符的便捷方式(类似于标准 python 异常中的e.errno),你可以这样使用它:

try:
    ...
    raise ValidationError(u'Oops', code=0x800)
    ...

except ValidationError as e:
    print "Error code: ", e.code

【讨论】:

感谢您的回答!所以如果我想在表单验证后保留这段代码的值,我需要重写 _clean_fileds 方法吗? 那个或者看上面Daniel的评论,他们可能还在做这个,所以最好等一下,这样升级时就不会出现不兼容问题。

以上是关于表单 ValidationError 和错误代码的主要内容,如果未能解决你的问题,请参考以下文章

Django绑定表单无效,但未引发ValidationError

将 ValidationError 提升为字典时出错

Mongoose ValidationError:验证失败:需要路径

如果引发 ValidationError,删除链接会在 Django 管理内联表单集中消失

“验证错误:密码不能为空”但表单中没有密码字段

从 django 模型的保存方法中引发 ValidationError?