【问题标题】:Django: Overriding the clean() method in forms - question about raising errorsDjango:覆盖表单中的 clean() 方法 - 关于引发错误的问题
【发布时间】:2011-01-08 04:35:53
【问题描述】:

我在 clean 方法中一直在做这样的事情:

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 并且具有也可能导致错误的独特约束。如果有人知道这样的事情,那就太好了......

【问题讨论】:

    标签: django django-forms django-validation


    【解决方案1】:
    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)
    

    【讨论】:

    • Grrr.... 试图给这个 +1,但我不小心点击了两次,现在它说“投票太旧了,无法更改”grrr...无论如何,很好的答案:) 但我'我仍然有一个问题......我在 ModelForm 上有一个干净的方法,检查唯一约束很重要,但如果我这样做:如果错误:引发 forms.ValidationError(errors) super(CompetitionAddForm, self).clean() 那么要么是我的错误,要么是唯一约束错误:-/
    【解决方案2】:

    来自文档:

    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
    

    【讨论】:

    • 这很好用(我不确定我是否喜欢将错误消息附加到字段而不是整个表单,但实际上这样更有意义)和 ModelForm独特的约束也有效。所以我接受这个 - 谢谢! :)
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      add_error() 自动从cleaned_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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 2013-04-20
        • 1970-01-01
        • 2023-03-07
        相关资源
        最近更新 更多