Fixed #17840 -- Generalized named placeholders in form error messages
Also fixed plural messages for DecimalField.
This commit is contained in:
parent
9ac4dbd7b5
commit
be9ae693c4
|
@ -292,9 +292,18 @@ class FloatField(IntegerField):
|
||||||
class DecimalField(IntegerField):
|
class DecimalField(IntegerField):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Enter a number.'),
|
'invalid': _('Enter a number.'),
|
||||||
'max_digits': _('Ensure that there are no more than %s digits in total.'),
|
'max_digits': ungettext_lazy(
|
||||||
'max_decimal_places': _('Ensure that there are no more than %s decimal places.'),
|
'Ensure that there are no more than %(max)s digit in total.',
|
||||||
'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.')
|
'Ensure that there are no more than %(max)s digits in total.',
|
||||||
|
'max'),
|
||||||
|
'max_decimal_places': ungettext_lazy(
|
||||||
|
'Ensure that there are no more than %(max)s decimal place.',
|
||||||
|
'Ensure that there are no more than %(max)s decimal places.',
|
||||||
|
'max'),
|
||||||
|
'max_whole_digits': ungettext_lazy(
|
||||||
|
'Ensure that there are no more than %(max)s digit before the decimal point.',
|
||||||
|
'Ensure that there are no more than %(max)s digits before the decimal point.',
|
||||||
|
'max'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs):
|
def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs):
|
||||||
|
@ -341,11 +350,15 @@ class DecimalField(IntegerField):
|
||||||
whole_digits = digits - decimals
|
whole_digits = digits - decimals
|
||||||
|
|
||||||
if self.max_digits is not None and digits > self.max_digits:
|
if self.max_digits is not None and digits > self.max_digits:
|
||||||
raise ValidationError(self.error_messages['max_digits'] % self.max_digits)
|
raise ValidationError(self.error_messages['max_digits'] % {
|
||||||
|
'max': self.max_digits})
|
||||||
if self.decimal_places is not None and decimals > self.decimal_places:
|
if self.decimal_places is not None and decimals > self.decimal_places:
|
||||||
raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places)
|
raise ValidationError(self.error_messages['max_decimal_places'] % {
|
||||||
if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places):
|
'max': self.decimal_places})
|
||||||
raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places))
|
if (self.max_digits is not None and self.decimal_places is not None
|
||||||
|
and whole_digits > (self.max_digits - self.decimal_places)):
|
||||||
|
raise ValidationError(self.error_messages['max_whole_digits'] % {
|
||||||
|
'max': (self.max_digits - self.decimal_places)})
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def widget_attrs(self, widget):
|
def widget_attrs(self, widget):
|
||||||
|
|
|
@ -1039,9 +1039,9 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||||
hidden_widget = MultipleHiddenInput
|
hidden_widget = MultipleHiddenInput
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'list': _('Enter a list of values.'),
|
'list': _('Enter a list of values.'),
|
||||||
'invalid_choice': _('Select a valid choice. %s is not one of the'
|
'invalid_choice': _('Select a valid choice. %(value)s is not one of the'
|
||||||
' available choices.'),
|
' available choices.'),
|
||||||
'invalid_pk_value': _('"%s" is not a valid value for a primary key.')
|
'invalid_pk_value': _('"%(pk)s" is not a valid value for a primary key.')
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, queryset, cache_choices=False, required=True,
|
def __init__(self, queryset, cache_choices=False, required=True,
|
||||||
|
@ -1063,12 +1063,12 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||||
try:
|
try:
|
||||||
self.queryset.filter(**{key: pk})
|
self.queryset.filter(**{key: pk})
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError(self.error_messages['invalid_pk_value'] % pk)
|
raise ValidationError(self.error_messages['invalid_pk_value'] % {'pk': pk})
|
||||||
qs = self.queryset.filter(**{'%s__in' % key: value})
|
qs = self.queryset.filter(**{'%s__in' % key: value})
|
||||||
pks = set([force_text(getattr(o, key)) for o in qs])
|
pks = set([force_text(getattr(o, key)) for o in qs])
|
||||||
for val in value:
|
for val in value:
|
||||||
if force_text(val) not in pks:
|
if force_text(val) not in pks:
|
||||||
raise ValidationError(self.error_messages['invalid_choice'] % val)
|
raise ValidationError(self.error_messages['invalid_choice'] % {'value': val})
|
||||||
# Since this overrides the inherited ModelChoiceField.clean
|
# Since this overrides the inherited ModelChoiceField.clean
|
||||||
# we run custom validators here
|
# we run custom validators here
|
||||||
self.run_validators(value)
|
self.run_validators(value)
|
||||||
|
|
|
@ -60,9 +60,9 @@ class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
'invalid': 'INVALID',
|
'invalid': 'INVALID',
|
||||||
'min_value': 'MIN VALUE IS %(limit_value)s',
|
'min_value': 'MIN VALUE IS %(limit_value)s',
|
||||||
'max_value': 'MAX VALUE IS %(limit_value)s',
|
'max_value': 'MAX VALUE IS %(limit_value)s',
|
||||||
'max_digits': 'MAX DIGITS IS %s',
|
'max_digits': 'MAX DIGITS IS %(max)s',
|
||||||
'max_decimal_places': 'MAX DP IS %s',
|
'max_decimal_places': 'MAX DP IS %(max)s',
|
||||||
'max_whole_digits': 'MAX DIGITS BEFORE DP IS %s',
|
'max_whole_digits': 'MAX DIGITS BEFORE DP IS %(max)s',
|
||||||
}
|
}
|
||||||
f = DecimalField(min_value=5, max_value=10, error_messages=e)
|
f = DecimalField(min_value=5, max_value=10, error_messages=e)
|
||||||
self.assertFormErrors(['REQUIRED'], f.clean, '')
|
self.assertFormErrors(['REQUIRED'], f.clean, '')
|
||||||
|
@ -254,7 +254,7 @@ class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
# ModelMultipleChoiceField
|
# ModelMultipleChoiceField
|
||||||
e = {
|
e = {
|
||||||
'required': 'REQUIRED',
|
'required': 'REQUIRED',
|
||||||
'invalid_choice': '%s IS INVALID CHOICE',
|
'invalid_choice': '%(value)s IS INVALID CHOICE',
|
||||||
'list': 'NOT A LIST OF VALUES',
|
'list': 'NOT A LIST OF VALUES',
|
||||||
}
|
}
|
||||||
f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
||||||
|
|
Loading…
Reference in New Issue