Author: Honza_Kral
Date: 2009-06-01 10:38:34 -0500 (Mon, 01 Jun 2009)
New Revision: 10868

Modified:
   django/branches/soc2009/model-validation/django/db/models/fields/__init__.py
   django/branches/soc2009/model-validation/django/db/models/fields/related.py
   
django/branches/soc2009/model-validation/tests/regressiontests/model_fields/tests.py
Log:
[soc2009/model-validation] Implemented some basic validation on model Fields 
including basic tests.

Modified: 
django/branches/soc2009/model-validation/django/db/models/fields/__init__.py
===================================================================
--- 
django/branches/soc2009/model-validation/django/db/models/fields/__init__.py    
    2009-06-01 15:38:11 UTC (rev 10867)
+++ 
django/branches/soc2009/model-validation/django/db/models/fields/__init__.py    
    2009-06-01 15:38:34 UTC (rev 10868)
@@ -117,7 +117,33 @@
         Returns the converted value. Subclasses should override this.
         """
         return value
+    
+    def validate(self, value, model_instance):
+        """
+        Validates value and throws ValidationError. Subclasses should override
+        this to provide validation logic.
+        """
+        if not self.editable:
+            # skip validation for non-editable fields
+            return
+        if self._choices and value:
+            if not value in dict(self.choices):
+                raise exceptions.ValidationError(_('Value %r is not a valid 
choice.') % value)
 
+        if value is None and not self.null:
+            raise exceptions.ValidationError(
+                ugettext_lazy("This field cannot be null."))
+
+    def clean(self, value, model_instance):
+        """
+        Convert the value's type and wun validation. Validation errors from 
to_python
+        and validate are propagated. The correct value is returned if no error 
is 
+        raised.
+        """
+        value = self.to_python(value)
+        self.validate(value, model_instance)
+        return value
+
     def db_type(self):
         """
         Returns the database column data type for this field, taking into
@@ -354,6 +380,9 @@
         except (TypeError, ValueError):
             raise exceptions.ValidationError(
                 _("This value must be an integer."))
+        
+    def validate(self, value, model_instance):
+        pass
 
     def get_db_prep_value(self, value):
         if value is None:
@@ -417,14 +446,8 @@
         return "CharField"
 
     def to_python(self, value):
-        if isinstance(value, basestring):
+        if isinstance(value, basestring) or value is None:
             return value
-        if value is None:
-            if self.null:
-                return value
-            else:
-                raise exceptions.ValidationError(
-                    ugettext_lazy("This field cannot be null."))
         return smart_unicode(value)
 
     def formfield(self, **kwargs):

Modified: 
django/branches/soc2009/model-validation/django/db/models/fields/related.py
===================================================================
--- django/branches/soc2009/model-validation/django/db/models/fields/related.py 
2009-06-01 15:38:11 UTC (rev 10867)
+++ django/branches/soc2009/model-validation/django/db/models/fields/related.py 
2009-06-01 15:38:34 UTC (rev 10868)
@@ -678,6 +678,11 @@
 
         self.db_index = True
 
+    def validate(self, value, model_instance):
+        if self.rel.parent_link:
+            return
+        super(ForeignKey, self).validate(value, model_instance)
+
     def get_attname(self):
         return '%s_id' % self.name
 
@@ -766,6 +771,14 @@
             return None
         return super(OneToOneField, self).formfield(**kwargs)
 
+    def save_form_data(self, instance, data):
+        # FIXME: is this a hack, or what? it works, but I don't really know 
why 
+        if isinstance(data, self.rel.to):
+            setattr(instance, self.name, data)
+        else:
+            setattr(instance, self.attname, data)
+
+
 class ManyToManyField(RelatedField, Field):
     def __init__(self, to, **kwargs):
         try:

Modified: 
django/branches/soc2009/model-validation/tests/regressiontests/model_fields/tests.py
===================================================================
--- 
django/branches/soc2009/model-validation/tests/regressiontests/model_fields/tests.py
        2009-06-01 15:38:11 UTC (rev 10867)
+++ 
django/branches/soc2009/model-validation/tests/regressiontests/model_fields/tests.py
        2009-06-01 15:38:34 UTC (rev 10868)
@@ -132,3 +132,45 @@
         bs = BigS.objects.get(pk=bs.pk)
         self.assertEqual(bs.s, 'slug'*50)
 
+class ValidationTest(django.test.TestCase):
+    def test_charfield_cleans_empty_string(self):
+        f = models.CharField()
+        self.assertEqual('', f.clean('', None))
+
+    def test_integerfield_cleans_valid_string(self):
+        f = models.IntegerField()
+        self.assertEqual(2, f.clean('2', None))
+
+    def test_integerfield_raises_error_on_invalid_intput(self):
+        f = models.IntegerField()
+        self.assertRaises(ValidationError, f.clean, "a", None)
+
+    def test_charfield_with_choices_cleans_valid_choice(self):
+        f = models.CharField(choices=[('a','A'), ('b','B')])
+        self.assertEqual('a', f.clean('a', None))
+
+    def test_charfield_with_choices_raises_error_on_invalid_choice(self):
+        f = models.CharField(choices=[('a','A'), ('b','B')])
+        self.assertRaises(ValidationError, f.clean, "not a", None)
+
+    def test_nullable_integerfield_cleans_none(self):
+        f = models.IntegerField(null=True)
+        self.assertEqual(None, f.clean(None, None))
+
+    def test_integerfield_raises_error_on_empty_input(self):
+        f = models.IntegerField(null=False)
+        self.assertRaises(ValidationError, f.clean, None, None)
+        self.assertRaises(ValidationError, f.clean, '', None)
+
+    def test_charfield_raises_error_on_empty_input(self):
+        f = models.CharField(null=False)
+        self.assertRaises(ValidationError, f.clean, None, None)
+
+    def test_datefield_cleans_date(self):
+        f = models.DateField()
+        self.assertEqual(datetime.date(2008, 10, 10), f.clean('2008-10-10', 
None))
+
+    def test_boolean_field_doesnt_accept_empty_input(self):
+        f = models.BooleanField()
+        self.assertRaises(ValidationError, f.clean, None, None)
+


--~--~---------~--~----~------------~-------~--~----~
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