diff --git a/django/forms/fields.py b/django/forms/fields.py
index d16b501..0bfc84a 100644
a
|
b
|
class DecimalField(Field):
|
281 | 281 | 'invalid': _('Enter a number.'), |
282 | 282 | 'max_value': _('Ensure this value is less than or equal to %(limit_value)s.'), |
283 | 283 | 'min_value': _('Ensure this value is greater than or equal to %(limit_value)s.'), |
284 | | 'max_digits': _('Ensure that there are no more than %s digits in total.'), |
285 | | 'max_decimal_places': _('Ensure that there are no more than %s decimal places.'), |
286 | | 'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.') |
| 284 | 'max_digits': _('Ensure that there are no more than %(max)s digits in total.'), |
| 285 | 'max_decimal_places': _('Ensure that there are no more than %(max)s decimal places.'), |
| 286 | 'max_whole_digits': _('Ensure that there are no more than %(max)s digits before the decimal point.') |
287 | 287 | } |
288 | 288 | |
289 | 289 | def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): |
… |
… |
class DecimalField(Field):
|
336 | 336 | whole_digits = digits - decimals |
337 | 337 | |
338 | 338 | if self.max_digits is not None and digits > self.max_digits: |
339 | | raise ValidationError(self.error_messages['max_digits'] % self.max_digits) |
| 339 | raise ValidationError(self.error_messages['max_digits'] % { |
| 340 | 'max': self.max_digits}) |
340 | 341 | if self.decimal_places is not None and decimals > self.decimal_places: |
341 | | raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) |
342 | | if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): |
343 | | raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) |
| 342 | raise ValidationError(self.error_messages['max_decimal_places'] % { |
| 343 | 'max': self.decimal_places}) |
| 344 | if (self.max_digits is not None and self.decimal_places is not None |
| 345 | and whole_digits > (self.max_digits - self.decimal_places)): |
| 346 | raise ValidationError(self.error_messages['max_whole_digits'] % { |
| 347 | 'max': (self.max_digits - self.decimal_places)}) |
344 | 348 | return value |
345 | 349 | |
346 | 350 | class BaseTemporalField(Field): |
diff --git a/django/forms/models.py b/django/forms/models.py
index 837da74..98294c6 100644
a
|
b
|
class ModelMultipleChoiceField(ModelChoiceField):
|
1018 | 1018 | hidden_widget = MultipleHiddenInput |
1019 | 1019 | default_error_messages = { |
1020 | 1020 | 'list': _('Enter a list of values.'), |
1021 | | 'invalid_choice': _('Select a valid choice. %s is not one of the' |
| 1021 | 'invalid_choice': _('Select a valid choice. %(choice)s is not one of the' |
1022 | 1022 | ' available choices.'), |
1023 | | 'invalid_pk_value': _('"%s" is not a valid value for a primary key.') |
| 1023 | 'invalid_pk_value': _('"%(pk)s" is not a valid value for a primary key.') |
1024 | 1024 | } |
1025 | 1025 | |
1026 | 1026 | def __init__(self, queryset, cache_choices=False, required=True, |
… |
… |
class ModelMultipleChoiceField(ModelChoiceField):
|
1042 | 1042 | try: |
1043 | 1043 | self.queryset.filter(**{key: pk}) |
1044 | 1044 | except ValueError: |
1045 | | raise ValidationError(self.error_messages['invalid_pk_value'] % pk) |
| 1045 | raise ValidationError(self.error_messages['invalid_pk_value'] % {'pk': pk}) |
1046 | 1046 | qs = self.queryset.filter(**{'%s__in' % key: value}) |
1047 | 1047 | pks = set([force_text(getattr(o, key)) for o in qs]) |
1048 | 1048 | for val in value: |
1049 | 1049 | if force_text(val) not in pks: |
1050 | | raise ValidationError(self.error_messages['invalid_choice'] % val) |
| 1050 | raise ValidationError(self.error_messages['invalid_choice'] % {'choice': val}) |
1051 | 1051 | # Since this overrides the inherited ModelChoiceField.clean |
1052 | 1052 | # we run custom validators here |
1053 | 1053 | self.run_validators(value) |
diff --git a/tests/regressiontests/forms/tests/error_messages.py b/tests/regressiontests/forms/tests/error_messages.py
index b76e122..6a07e1e 100644
a
|
b
|
class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
|
60 | 60 | 'invalid': 'INVALID', |
61 | 61 | 'min_value': 'MIN VALUE IS %(limit_value)s', |
62 | 62 | 'max_value': 'MAX VALUE IS %(limit_value)s', |
63 | | 'max_digits': 'MAX DIGITS IS %s', |
64 | | 'max_decimal_places': 'MAX DP IS %s', |
65 | | 'max_whole_digits': 'MAX DIGITS BEFORE DP IS %s', |
| 63 | 'max_digits': 'MAX DIGITS IS %(max)s', |
| 64 | 'max_decimal_places': 'MAX DP IS %(max)s', |
| 65 | 'max_whole_digits': 'MAX DIGITS BEFORE DP IS %(max)s', |
66 | 66 | } |
67 | 67 | f = DecimalField(min_value=5, max_value=10, error_messages=e) |
68 | 68 | self.assertFormErrors(['REQUIRED'], f.clean, '') |
… |
… |
class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
|
254 | 254 | # ModelMultipleChoiceField |
255 | 255 | e = { |
256 | 256 | 'required': 'REQUIRED', |
257 | | 'invalid_choice': '%s IS INVALID CHOICE', |
| 257 | 'invalid_choice': '%(choice)s IS INVALID CHOICE', |
258 | 258 | 'list': 'NOT A LIST OF VALUES', |
259 | 259 | } |
260 | 260 | f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) |