diff --git a/django/core/exceptions.py b/django/core/exceptions.py index 9f9aeb29a5..29da67cfa6 100644 --- a/django/core/exceptions.py +++ b/django/core/exceptions.py @@ -44,6 +44,7 @@ class ValidationError(Exception): """ if isinstance(message, dict): self.message_dict = message + # Reduce each list of messages into a single list. message = reduce(operator.add, message.values()) if isinstance(message, list): diff --git a/django/db/models/base.py b/django/db/models/base.py index d04df5d8c0..c83b0fd5b5 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -819,8 +819,9 @@ class Model(object): error_list.append(message) else: error_list.extend(e.messages) + # Form.clean() is run even if other validation fails, so do the + # same with Model.validate() for consistency. try: - # TODO: run this only if not errors?? self.validate() except ValidationError, e: if hasattr(e, 'message_dict'): diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index edfda48cec..96fc36f0ab 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -149,7 +149,6 @@ class Field(object): for k in translated_keys: self.error_messages[k] = _(self.error_messages[k]) - def __cmp__(self, other): # This is needed because bisect does not take a comparison function. return cmp(self.creation_counter, other.creation_counter) @@ -177,8 +176,8 @@ class Field(object): errors = [] for v in self.validators: - # don't run complex validators since they need obj - # and must therefore be run on the model level + # Don't run complex validators since they need the model instance + # and must therefore be run on the model level. if not isinstance(v, validators.ComplexValidator): try: v(value) @@ -192,14 +191,14 @@ class Field(object): errors.extend(e.messages) if errors: raise exceptions.ValidationError(errors) - + 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 + # Skip validation for non-editable fields. return if self._choices and value: if not value in dict(self.choices): @@ -208,15 +207,12 @@ class Field(object): if value is None and not self.null: raise exceptions.ValidationError(self.error_messages['null']) - # cannot do if not value because of 0 passed to integer fields if not self.blank and value in validators.EMPTY_VALUES: raise exceptions.ValidationError(self.error_messages['blank']) - - def clean(self, value, model_instance): """ - Convert the value's type and wun validation. Validation errors from to_python + Convert the value's type and run validation. Validation errors from to_python and validate are propagated. The correct value is returned if no error is raised. """ @@ -493,7 +489,7 @@ class AutoField(Field): return int(value) except (TypeError, ValueError): raise exceptions.ValidationError(self.error_messages['invalid']) - + def validate(self, value, model_instance): pass @@ -1112,3 +1108,4 @@ class XMLField(TextField): def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs): self.schema_path = schema_path Field.__init__(self, verbose_name, name, **kwargs) + diff --git a/django/forms/forms.py b/django/forms/forms.py index a009952e22..5b8a4d0454 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -284,14 +284,14 @@ class BaseForm(StrAndUnicode): if name in self.cleaned_data: del self.cleaned_data[name] - # run complex validators after the fields have been cleaned since they - # need access to all_values + # Run complex validators after the fields have been cleaned since they + # need access to all_values. for name, field in self.fields.items(): if not name in self.cleaned_data: continue failed = False for v in field.validators: - # skip noncomplex validators, they have already been run on the Field + # Skip noncomplex validators, they have already been run on the field. if not isinstance(v, ComplexValidator): continue try: diff --git a/django/forms/util.py b/django/forms/util.py index b6722108c9..1a1d823495 100644 --- a/django/forms/util.py +++ b/django/forms/util.py @@ -2,8 +2,8 @@ from django.utils.html import conditional_escape from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe -# import ValidationError so that it can be imported from this -# module to maintain backwards compatibility +# Import ValidationError so that it can be imported from this +# module to maintain backwards compatibility. from django.core.exceptions import ValidationError def flatatt(attrs): diff --git a/tests/modeltests/validation/test_unique.py b/tests/modeltests/validation/test_unique.py index 944697100f..618a5578c7 100644 --- a/tests/modeltests/validation/test_unique.py +++ b/tests/modeltests/validation/test_unique.py @@ -39,7 +39,7 @@ class PerformUniqueChecksTest(unittest.TestCase): super(PerformUniqueChecksTest, self).tearDown() def test_primary_key_unique_check_performed_when_adding(self): - "Check#12132" + """Regression test for #12132""" l = len(connection.queries) mtv = ModelToValidate(number=10, name='Some Name') setattr(mtv, '_adding', True) @@ -47,7 +47,7 @@ class PerformUniqueChecksTest(unittest.TestCase): self.assertEqual(l+1, len(connection.queries)) def test_primary_key_unique_check_not_performed_when_not_adding(self): - "Check#12132" + """Regression test for #12132""" l = len(connection.queries) mtv = ModelToValidate(number=10, name='Some Name') mtv.clean()