diff --git a/django/forms/fields.py b/django/forms/fields.py
index 621d380..1b819d7 100644
a
|
b
|
class FloatField(IntegerField):
|
299 | 299 | class DecimalField(IntegerField): |
300 | 300 | default_error_messages = { |
301 | 301 | 'invalid': _('Enter a number.'), |
302 | | 'max_digits': _('Ensure that there are no more than %s digits in total.'), |
303 | | 'max_decimal_places': _('Ensure that there are no more than %s decimal places.'), |
304 | | 'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.') |
| 302 | 'max_digits': ungettext_lazy( |
| 303 | 'Ensure that there are no more than %(max)s digit in total.', |
| 304 | 'Ensure that there are no more than %(max)s digits in total.', |
| 305 | 'max'), |
| 306 | 'max_decimal_places': ungettext_lazy( |
| 307 | 'Ensure that there are no more than %(max)s decimal place.', |
| 308 | 'Ensure that there are no more than %(max)s decimal places.', |
| 309 | 'max'), |
| 310 | 'max_whole_digits': ungettext_lazy( |
| 311 | 'Ensure that there are no more than %(max)s digit before the decimal point.', |
| 312 | 'Ensure that there are no more than %(max)s digits before the decimal point.', |
| 313 | 'max'), |
305 | 314 | } |
306 | 315 | |
307 | 316 | def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): |
… |
… |
class DecimalField(IntegerField):
|
348 | 357 | whole_digits = digits - decimals |
349 | 358 | |
350 | 359 | if self.max_digits is not None and digits > self.max_digits: |
351 | | raise ValidationError(self.error_messages['max_digits'] % self.max_digits) |
| 360 | raise ValidationError(self.error_messages['max_digits'] % { |
| 361 | 'max': self.max_digits}) |
352 | 362 | if self.decimal_places is not None and decimals > self.decimal_places: |
353 | | raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) |
354 | | if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): |
355 | | raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) |
| 363 | raise ValidationError(self.error_messages['max_decimal_places'] % { |
| 364 | 'max': self.decimal_places}) |
| 365 | if (self.max_digits is not None and self.decimal_places is not None |
| 366 | and whole_digits > (self.max_digits - self.decimal_places)): |
| 367 | raise ValidationError(self.error_messages['max_whole_digits'] % { |
| 368 | 'max': (self.max_digits - self.decimal_places)}) |
356 | 369 | return value |
357 | 370 | |
358 | 371 | def widget_attrs(self, widget): |
diff --git a/django/forms/models.py b/django/forms/models.py
index c4e0301..1dda04b 100644
a
|
b
|
class ModelMultipleChoiceField(ModelChoiceField):
|
1015 | 1015 | hidden_widget = MultipleHiddenInput |
1016 | 1016 | default_error_messages = { |
1017 | 1017 | 'list': _('Enter a list of values.'), |
1018 | | 'invalid_choice': _('Select a valid choice. %s is not one of the' |
| 1018 | 'invalid_choice': _('Select a valid choice. %(choice)s is not one of the' |
1019 | 1019 | ' available choices.'), |
1020 | | 'invalid_pk_value': _('"%s" is not a valid value for a primary key.') |
| 1020 | 'invalid_pk_value': _('"%(pk)s" is not a valid value for a primary key.') |
1021 | 1021 | } |
1022 | 1022 | |
1023 | 1023 | def __init__(self, queryset, cache_choices=False, required=True, |
… |
… |
class ModelMultipleChoiceField(ModelChoiceField):
|
1039 | 1039 | try: |
1040 | 1040 | self.queryset.filter(**{key: pk}) |
1041 | 1041 | except ValueError: |
1042 | | raise ValidationError(self.error_messages['invalid_pk_value'] % pk) |
| 1042 | raise ValidationError(self.error_messages['invalid_pk_value'] % {'pk': pk}) |
1043 | 1043 | qs = self.queryset.filter(**{'%s__in' % key: value}) |
1044 | 1044 | pks = set([force_text(getattr(o, key)) for o in qs]) |
1045 | 1045 | for val in value: |
1046 | 1046 | if force_text(val) not in pks: |
1047 | | raise ValidationError(self.error_messages['invalid_choice'] % val) |
| 1047 | raise ValidationError(self.error_messages['invalid_choice'] % {'choice': val}) |
1048 | 1048 | # Since this overrides the inherited ModelChoiceField.clean |
1049 | 1049 | # we run custom validators here |
1050 | 1050 | 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) |