使用模型表单创建自定义错误消息

Posted

技术标签:

【中文标题】使用模型表单创建自定义错误消息【英文标题】:Create Custom Error Messages with Model Forms 【发布时间】:2011-03-27 02:07:19 【问题描述】:

我可以看到使用表单时如何在字段中添加错误消息,但是模型表单呢?

这是我的测试模型:

class Author(models.Model):
    first_name = models.CharField(max_length=125)
    last_name = models.CharField(max_length=125)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

我的模型形式:

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

字段上的错误消息:first_namelast_name 是:

此字段为必填项

如何在模型表单中更改它?

【问题讨论】:

【参考方案1】:

最简单的方法是重写 clean 方法:

class AuthorForm(forms.ModelForm):
   class Meta:
      model = Author
   def clean(self):
      if self.cleaned_data.get('name')=="":
         raise forms.ValidationError('No name!')
      return self.cleaned_data

【讨论】:

【参考方案2】:

简单的情况可以specify custom error messages

class AuthorForm(forms.ModelForm):
    first_name = forms.CharField(error_messages='required': 'Please let us know what to call you!')
    class Meta:
        model = Author

【讨论】:

非常感谢。我不知道这样做的结果是什么。文档说“声明的字段将覆盖使用模型属性生成的默认字段”所以我应该很好。我还必须在模型表单字段上再次设置 max_field。 真的需要在表单中重复字段声明吗? django 引以为豪的 DRY 原则怎么样? 大声笑,伙计,我认为 OP 想要使用模型中的表单,但不想两次声明表单。 我认为对于客户端而言,明确比 DRY 更重要。【参考方案3】:

我也多次想过这个问题。这就是为什么我最终为 ModelForm 类编写了一个小扩展,它允许我通过 Meta 类设置任意字段属性——包括错误消息。代码和解释可以在这里找到:http://blog.brendel.com/2012/01/django-modelforms-setting-any-field.html

您将能够执行以下操作:

class AuthorForm(ExtendedMetaModelForm):
    class Meta:
        model = Author
        field_args = 
            "first_name" : 
                "error_messages" : 
                    "required" : "Please let us know what to call you!"
                
            
        

我想这就是你要找的,对吧?

【讨论】:

这是一个很好的方法。当然比重新定义表单域更 DRY。 @suda 您并没有真正重新定义,而是根据关联的模型覆盖默认行为。类似于将输入更改为文本区域,您将覆盖默认值。【参考方案4】:

另一种简单的方法是在 init 中覆盖它。

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

    def __init__(self, *args, **kwargs):
        super(AuthorForm, self).__init__(*args, **kwargs)

        # add custom error messages
        self.fields['name'].error_messages.update(
            'required': 'Please let us know what to call you!',
        )

【讨论】:

这是比这个线程中的所有其他解决方案更好的解决方案,因为 1)您不必使用任何扩展 2)您不必重写整个表单字段定义,因为它取决于模型字段。 +1 请注意,您必须像 self.fields['name'].error_messages['required'] = 'Please let us know what to call you!' 这样使用它或使用 .update() 方法,否则您会重置所有其他错误消息。【参考方案5】:

New in Django 1.6:

ModelForm 接受几个新的 Meta 选项。

localized_fields 列表中包含的字段将被本地化(通过在表单字段上设置 localize)。 标签、help_texts 和 error_messages 选项可用于自定义默认字段,详情请参阅Overriding the default fields。

由此而来:

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        labels = 
            'name': _('Writer'),
        
        help_texts = 
            'name': _('Some useful help text.'),
        
        error_messages = 
            'name': 
                'max_length': _("This writer's name is too long."),
            ,
        

相关:Django's ModelForm - where is the list of Meta options?

【讨论】:

我不理解自定义错误消息文本周围的 _(),所以我把它拿出来了。但这是第一个对我有用的 sn-p。我在 django 1.6 上。谢谢你,先生! 不客气!如果你很好奇,下划线函数是国际化实用程序的常用快捷方式:***.com/questions/2964244/… 我认为这应该是公认的答案,因为它遵循 DRY 原则。使用 ModelForm 时,不需要再次声明字段,也不需要重写方法。 只有在没有刻意定义字段和小部件时才使用 Meta 类中的默认值。如果它们是有意定义的,则应在此处或在__init__ 方法中定义错误消息。 ***.com/questions/57424228/…【参考方案6】:

根据 jamesmfriedman 的回答,我有一个更清洁的解决方案。 此解决方案更加干燥,尤其是在您有很多字段的情况下。

custom_errors = 
    'required': 'Your custom error message'


class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

    def __init__(self, *args, **kwargs):
        super(AuthorForm, self).__init__(*args, **kwargs)

        for field in self.fields:
            self.fields[field].error_messages = custom_errors

【讨论】:

【参考方案7】:

您可以通过覆盖clean()method 并使用self.add_error(field, message) 轻松检查并放置自定义错误消息:

def clean(self):
    super(PromotionForm, self).clean()
    error_message = ''
    field = ''
    # reusable check
    if self.cleaned_data['reusable'] == 0:
        error_message = 'reusable should not be zero'
        field = 'reusable'
        self.add_error(field, error_message)
        raise ValidationError(error_message)

    return self.cleaned_data

【讨论】:

以上是关于使用模型表单创建自定义错误消息的主要内容,如果未能解决你的问题,请参考以下文章

将自定义验证错误消息按元素合并到表单对象中

Symfony 1.4:表单中 CSRF 的自定义错误消息

实现 css 自定义错误与其他表单字段重叠

自定义 HTML5 表单验证最初不显示自定义错误

如何根据 Angular 2 中的自定义验证规则显示错误消息?

Laravel - 多个字段的相同自定义错误消息