From a43c2f50c2106d868045c7858de219de9717836c Mon Sep 17 00:00:00 2001 From: Ramiro Morales Date: Wed, 29 Dec 2010 01:18:11 +0000 Subject: [PATCH] Fixed #7726 -- Added validation of max_digits and decimal_places options to DecimalField model field. Thanks theevilgeek for the report and elbarto for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@15094 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/management/validation.py | 9 +++++++++ docs/ref/models/fields.txt | 5 +++-- tests/modeltests/invalid_models/models.py | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/django/core/management/validation.py b/django/core/management/validation.py index f78fa87b33..2eb6340de9 100644 --- a/django/core/management/validation.py +++ b/django/core/management/validation.py @@ -53,11 +53,14 @@ def get_validation_errors(outfile, app=None): except (ValueError, TypeError): e.add(opts, '"%s": CharFields require a "max_length" attribute that is a positive integer.' % f.name) if isinstance(f, models.DecimalField): + decimalp_ok, mdigits_ok = False, False decimalp_msg ='"%s": DecimalFields require a "decimal_places" attribute that is a non-negative integer.' try: decimal_places = int(f.decimal_places) if decimal_places < 0: e.add(opts, decimalp_msg % f.name) + else: + decimalp_ok = True except (ValueError, TypeError): e.add(opts, decimalp_msg % f.name) mdigits_msg = '"%s": DecimalFields require a "max_digits" attribute that is a positive integer.' @@ -65,8 +68,14 @@ def get_validation_errors(outfile, app=None): max_digits = int(f.max_digits) if max_digits <= 0: e.add(opts, mdigits_msg % f.name) + else: + mdigits_ok = True except (ValueError, TypeError): e.add(opts, mdigits_msg % f.name) + invalid_values_msg = '"%s": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute.' + if decimalp_ok and mdigits_ok: + if decimal_places >= max_digits: + e.add(opts, invalid_values_msg % f.name) if isinstance(f, models.FileField) and not f.upload_to: e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name) if isinstance(f, models.ImageField): diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 0399eccf67..583dfb499c 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -437,11 +437,12 @@ A fixed-precision decimal number, represented in Python by a .. attribute:: DecimalField.max_digits - The maximum number of digits allowed in the number + The maximum number of digits allowed in the number. Note that this number + must be greater than ``decimal_places``, if it exists. .. attribute:: DecimalField.decimal_places - The number of decimal places to store with the number + The number of decimal places to store with the number. For example, to store numbers up to 999 with a resolution of 2 decimal places, you'd use:: diff --git a/tests/modeltests/invalid_models/models.py b/tests/modeltests/invalid_models/models.py index 2788aa077e..ab9edd6461 100644 --- a/tests/modeltests/invalid_models/models.py +++ b/tests/modeltests/invalid_models/models.py @@ -14,6 +14,8 @@ class FieldErrors(models.Model): decimalfield = models.DecimalField() decimalfield2 = models.DecimalField(max_digits=-1, decimal_places=-1) decimalfield3 = models.DecimalField(max_digits="bad", decimal_places="bad") + decimalfield4 = models.DecimalField(max_digits=9, decimal_places=10) + decimalfield5 = models.DecimalField(max_digits=10, decimal_places=10) filefield = models.FileField() choices = models.CharField(max_length=10, choices='bad') choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)]) @@ -241,6 +243,8 @@ invalid_models.fielderrors: "decimalfield2": DecimalFields require a "decimal_pl invalid_models.fielderrors: "decimalfield2": DecimalFields require a "max_digits" attribute that is a positive integer. invalid_models.fielderrors: "decimalfield3": DecimalFields require a "decimal_places" attribute that is a non-negative integer. invalid_models.fielderrors: "decimalfield3": DecimalFields require a "max_digits" attribute that is a positive integer. +invalid_models.fielderrors: "decimalfield4": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute. +invalid_models.fielderrors: "decimalfield5": DecimalFields require a "max_digits" attribute value that is greater than the value of the "decimal_places" attribute. invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute. invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list). invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples.