Django 覆盖默认表单错误信息

61

如何覆盖项目中所有应用程序(或至少一个应用程序)的默认表单错误消息(例如:需要使用其他语言)?

谢谢!

9个回答

88
最简单的方法是将您的默认错误集合提供给表单字段定义。表单字段可以使用一个命名参数来接受这个默认错误集合。例如:

最简单的方法是在表单字段定义中提供您的默认错误集合。表单字段可以使用一个命名参数来接受该集合。例如:

my_default_errors = {
    'required': 'This field is required',
    'invalid': 'Enter a valid value'
}

class MyForm(forms.Form):
    some_field = forms.CharField(error_messages=my_default_errors)
    ....

是的。但我想要覆盖默认设置,并具有设置特定表单的灵活性... 在您的情况下,我将不得不手动合并默认和表单错误消息字典每次。 - Brock
@Brock 这还不错,你只需编写 my_default_errors.update({…}) 即可插入字段或表单特定值。 - Michael Mior

8
为了全局覆盖“required”错误消息,请在Field上设置default_error_messages类属性:
# form error message override
from django.forms import Field
from django.utils.translation import ugettext_lazy
Field.default_error_messages = {
    'required': ugettext_lazy("This field is mandatory."),
}

在任何字段被实例化之前,都需要进行这个操作,例如将其包含在settings.py中。


1
这只是猴子补丁,应该避免使用,因为这样你的应用程序更依赖于加载顺序(以及许多其他原因)。 - Darian Moody

7

我从Google来到这里,我需要覆盖表单中所有字段的默认所需消息,而不是每次定义新表单字段时都传递error_messages参数。此外,我还没有准备好深入研究i18n,因为该应用程序不需要多语言支持。这篇博客文章中的评论最接近我想要的内容:

http://davedash.com/2008/11/28/custom-error-messages-for-django-forms/

对于所有具有必填信息的表单字段,我所做的是:

class MyForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        for k, field in self.fields.items():
            if 'required' in field.error_messages:
                field.error_messages['required'] = 'You have to field this.'

class MUserForm(MyForm):
    user = forms.CharField(
        label="Username",
    )
    ....

你可能不想这样做,或者至少要小心。如果你在一个继承的表单上这样做,它也会改变父表单上的错误信息。 - Matthew Schinckel

3

嗯,似乎没有容易的解决方法。

在浏览 Django 代码时,我发现默认的错误消息被硬编码到每个表单字段类中,例如:

class CharField(Field):
    default_error_messages = {
        'max_length': _(u'Ensure this value has at most %(max)d characters (it has %(length)d).'),
        'min_length': _(u'Ensure this value has at least %(min)d characters (it has %(length)d).'),
    }

最简单的方法是使用error_messages参数,因此我不得不编写包装函数:

def DZForm(name, args = {}):
    error_messages = {
        'required': u'required',
        'invalid': u'invalid',
    }
    if 'error_messages' in args.keys():
        args['error_messages'] = error_messages.update(args['error_messages'])
    else:
        args['error_messages'] = error_messages
    return getattr(forms, name)(**args)

如果有更优雅的方法,请分享给我们看看 :)
谢谢!

3

您可能想要查看Django出色的i18n支持


3

来自ProDjango书籍:

from django.forms import fields, util


class LatitudeField(fields.DecimalField):  
    default_error_messages = {
        'out_of_range': u'Value must be within -90 and 90.',
    }


    def clean(self, value):  
        value = super(LatitudeField, self).clean(value)  
        if not -90 <= value <= 90:  
            raise util.ValidationError(self.error_messages['out_of_range'])
        return value

3

假设我有一个名为BaseForm的类,其中包含一些error_messages字典,如下所示:

error_messages = {
    'required': 'This field is required',
    'caps': 'This field if case sensitive' 
}

我希望能够修改其中一个错误信息:

class MySpecialForm(BaseForm):
    def __init__(self, *args, **kwargs):
        super(MySpecialForm, self).__init__(*args, **kwargs)
        self.error_messages['caps'] = 'Hey, that CAPSLOCK is on!!!'

基本上,只需覆盖字典中的一个值。但我不确定在国际化方面如何运作。


这是一个很好且简单的解决方案,只要国际化不是问题。对我很有效。 - thms

-2
from django import forms
from django.utils.translation import gettext as _


class MyForm(forms.Form):
     # create form field
     subject = forms.CharField(required=True)

     # override one specific error message and leave the others unchanged
     # use gettext for translation
     subject.error_messages['required'] = _('Please enter a subject below.')

-6

既然这个页面在搜索中出现,也许即使问题已经老旧,我也值得加入我的$0.02。 (我还在适应Stack Overflow的特定礼仪。)

下划线(“_”)是ugettext_lazy的别名(如果这是正确的术语),只需查看带有“硬编码”消息的文件顶部的导入语句即可。 然后,Django的国际化文档应该会有所帮助,例如http://www.djangobook.com/en/2.0/chapter19/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接