Django:覆盖表单中的clean()方法 - 关于引发错误的问题

时间:2010-01-22 12:06:24

标签: django django-forms django-validation

我一直在用干净的方法做这样的事情:

if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
      raise forms.ValidationError('The start date cannot be later than the end date.')

但是那意味着表单一次只能引发其中一个错误。表单是否有办法引发这两个错误?

编辑#1 : 上述任何解决方案都很棒,但是会喜欢在以下场景中起作用的东西:

if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
      raise forms.ValidationError('The start date cannot be later than the end date.')
super(FooAddForm, self).clean()

其中FooAddForm是ModelForm并且具有可能也会导致错误的唯一约束。如果有人知道这样的话,那就太棒了......

4 个答案:

答案 0 :(得分:18)

来自文档:

https://docs.djangoproject.com/en/1.7/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

from django.forms.util import ErrorList

def clean(self):

  if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
    msg = 'The type and organization do not match.'
    self._errors['type'] = ErrorList([msg])
    del self.cleaned_data['type']

  if self.cleaned_data['start'] > self.cleaned_data['end']:
    msg = 'The start date cannot be later than the end date.'
    self._errors['start'] = ErrorList([msg])
    del self.cleaned_data['start']

  return self.cleaned_data

答案 1 :(得分:7)

errors = []
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      errors.append('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
     errors.append('The start date cannot be later than the end date.')

if errors:
    raise forms.ValidationError(errors)

答案 2 :(得分:3)

如果您希望将错误消息附加到表单而不是特定字段,则可以使用“__all__”键,如下所示:

msg = 'The type and organization do not match.'
self._errors['__all__'] = ErrorList([msg])

此外,正如Django文档所解释的那样:“如果要向特定字段添加新错误,则应检查密钥是否已存在于self._errors中。如果不存在,请创建新条目给定的密​​钥,持有一个空的ErrorList实例。在任何一种情况下,您都可以将错误消息附加到相关字段名称的列表中,并在显示表单时显示。“

答案 3 :(得分:3)

虽然它的旧帖子,如果您想要更少的代码,您可以使用add_error()方法添加错误消息。我正在扩展@ kemar的答案以显示用例:

add_error()会自动从cleaning_data字典中删除该字段,您无需手动删除它。 此外,你不必导入任何东西来使用它。

documentation is here

def clean(self):

  if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
    msg = 'The type and organization do not match.'
    self.add_error('type', msg)

  if self.cleaned_data['start'] > self.cleaned_data['end']:
    msg = 'The start date cannot be later than the end date.'
    self.add_error('start', msg)

  return self.cleaned_data