Author: russellm
Date: 2010-03-12 09:22:05 -0600 (Fri, 12 Mar 2010)
New Revision: 12768

Modified:
   django/trunk/django/core/management/validation.py
   django/trunk/tests/modeltests/invalid_models/models.py
Log:
Fixed #12404 -- Improved model validation for CharField and DecimalField. 
Thanks to tiliv for the report, josh for the patch, and Leo for the tests.

Modified: django/trunk/django/core/management/validation.py
===================================================================
--- django/trunk/django/core/management/validation.py   2010-03-12 14:45:56 UTC 
(rev 12767)
+++ django/trunk/django/core/management/validation.py   2010-03-12 15:22:05 UTC 
(rev 12768)
@@ -37,13 +37,26 @@
                 e.add(opts, '"%s": You can\'t use "id" as a field name, 
because each model automatically gets an "id" field if none of the fields have 
primary_key=True. You need to either remove/rename your "id" field or add 
primary_key=True to a field.' % f.name)
             if f.name.endswith('_'):
                 e.add(opts, '"%s": Field names cannot end with underscores, 
because this would lead to ambiguous queryset filters.' % f.name)
-            if isinstance(f, models.CharField) and f.max_length in (None, 0):
-                e.add(opts, '"%s": CharFields require a "max_length" 
attribute.' % f.name)
+            if isinstance(f, models.CharField):
+                try:
+                    max_length = int(f.max_length)
+                    if max_length <= 0:
+                        e.add(opts, '"%s": CharFields require a "max_length" 
attribute that is a positive integer.' % f.name)
+                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):
-                if f.decimal_places is None:
-                    e.add(opts, '"%s": DecimalFields require a 
"decimal_places" attribute.' % f.name)
-                if f.max_digits is None:
-                    e.add(opts, '"%s": DecimalFields require a "max_digits" 
attribute.' % f.name)
+                try:
+                    decimal_places = int(f.decimal_places)
+                    if decimal_places <= 0:
+                        e.add(opts, '"%s": DecimalFields require a 
"decimal_places" attribute that is a positive integer.' % f.name)
+                except (ValueError, TypeError):
+                    e.add(opts, '"%s": DecimalFields require a 
"decimal_places" attribute that is a positive integer.' % f.name)
+                try:
+                    max_digits = int(f.max_digits)
+                    if max_digits <= 0:
+                        e.add(opts, '"%s": DecimalFields require a 
"max_digits" attribute that is a positive integer.' % f.name)
+                except (ValueError, TypeError):
+                    e.add(opts, '"%s": DecimalFields require a "max_digits" 
attribute that is a positive integer.' % 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):

Modified: django/trunk/tests/modeltests/invalid_models/models.py
===================================================================
--- django/trunk/tests/modeltests/invalid_models/models.py      2010-03-12 
14:45:56 UTC (rev 12767)
+++ django/trunk/tests/modeltests/invalid_models/models.py      2010-03-12 
15:22:05 UTC (rev 12768)
@@ -8,7 +8,11 @@
 
 class FieldErrors(models.Model):
     charfield = models.CharField()
+    charfield2 = models.CharField(max_length=-1)
+    charfield3 = models.CharField(max_length="bad")
     decimalfield = models.DecimalField()
+    decimalfield2 = models.DecimalField(max_digits=-1, decimal_places=-1)
+    decimalfield3 = models.DecimalField(max_digits="bad", decimal_places="bad")
     filefield = models.FileField()
     choices = models.CharField(max_length=10, choices='bad')
     choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)])
@@ -203,9 +207,15 @@
     tgt = models.ForeignKey(FKTarget, to_field='good')
 
 
-model_errors = """invalid_models.fielderrors: "charfield": CharFields require 
a "max_length" attribute.
-invalid_models.fielderrors: "decimalfield": DecimalFields require a 
"decimal_places" attribute.
-invalid_models.fielderrors: "decimalfield": DecimalFields require a 
"max_digits" attribute.
+model_errors = """invalid_models.fielderrors: "charfield": CharFields require 
a "max_length" attribute that is a positive integer.
+invalid_models.fielderrors: "charfield2": CharFields require a "max_length" 
attribute that is a positive integer.
+invalid_models.fielderrors: "charfield3": CharFields require a "max_length" 
attribute that is a positive integer.
+invalid_models.fielderrors: "decimalfield": DecimalFields require a 
"decimal_places" attribute that is a positive integer.
+invalid_models.fielderrors: "decimalfield": DecimalFields require a 
"max_digits" attribute that is a positive integer.
+invalid_models.fielderrors: "decimalfield2": DecimalFields require a 
"decimal_places" attribute that is a positive integer.
+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 positive integer.
+invalid_models.fielderrors: "decimalfield3": DecimalFields require a 
"max_digits" attribute that is a positive integer.
 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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to