diff --git a/django/core/validators.py b/django/core/validators.py index 4515ca7a4f..6cd290fba9 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -135,26 +135,3 @@ class MaxLengthValidator(BaseValidator): message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).') code = 'max_length' - -class ComplexValidator(object): - def get_value(self, name, all_values, obj): - assert all_values or obj, "Either all_values or obj must be supplied" - - if all_values: - return all_values.get(name, None) - if obj: - return getattr(obj, name, None) - - - def __call__(self, value, all_values={}, obj=None): - raise NotImplementedError() - -class RequiredIfOtherFieldBlank(ComplexValidator): - def __init__(self, other_field): - self.other_field = other_field - - def __call__(self, value, all_values={}, obj=None): - if self.get_value(self.other_field, all_values, obj) in EMPTY_VALUES: - if value in EMPTY_VALUES: - raise ValidationError('This field is required if %s is blank.' % self.other_field) - diff --git a/django/db/models/base.py b/django/db/models/base.py index eace314fe8..660c570605 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -799,26 +799,6 @@ class Model(object): except ValidationError, e: errors[f.name] = e.messages - # run complex validators after the fields have been cleaned since they - # need access to model_instance. - for f in self._meta.fields: - if f.name in errors: - continue - - value = getattr(self, f.attname) - for v in f.validators: - if isinstance(v, validators.ComplexValidator): - try: - v(value, obj=self) - except ValidationError, e: - error_list = errors.setdefault(f.name, []) - if hasattr(e, 'code') and e.code in f.error_messages: - message = f.error_messages[e.code] - if e.params: - message = message % e.params - 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: diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 96fc36f0ab..5c364374a9 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -176,19 +176,16 @@ class Field(object): errors = [] for v in self.validators: - # 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) - except exceptions.ValidationError, e: - if hasattr(e, 'code') and e.code in self.error_messages: - message = self.error_messages[e.code] - if e.params: - message = message % e.params - errors.append(message) - else: - errors.extend(e.messages) + try: + v(value) + except exceptions.ValidationError, e: + if hasattr(e, 'code') and e.code in self.error_messages: + message = self.error_messages[e.code] + if e.params: + message = message % e.params + errors.append(message) + else: + errors.extend(e.messages) if errors: raise exceptions.ValidationError(errors) diff --git a/django/forms/fields.py b/django/forms/fields.py index 40e3d90d6a..23a88d62ed 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -130,19 +130,16 @@ class Field(object): return errors = [] for v in self.validators: - # don't run complex validators since they need all_values - # and must therefore be run on the form level - if not isinstance(v, validators.ComplexValidator): - try: - v(value) - except ValidationError, e: - if hasattr(e, 'code') and e.code in self.error_messages: - message = self.error_messages[e.code] - if e.params: - message = message % e.params - errors.append(message) - else: - errors.extend(e.messages) + try: + v(value) + except ValidationError, e: + if hasattr(e, 'code') and e.code in self.error_messages: + message = self.error_messages[e.code] + if e.params: + message = message % e.params + errors.append(message) + else: + errors.extend(e.messages) if errors: raise ValidationError(errors) diff --git a/django/forms/forms.py b/django/forms/forms.py index 5b8a4d0454..d484300a0d 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -3,7 +3,6 @@ Form classes """ from django.core.exceptions import ValidationError -from django.core.validators import ComplexValidator from django.utils.copycompat import deepcopy from django.utils.datastructures import SortedDict from django.utils.html import conditional_escape @@ -283,31 +282,6 @@ class BaseForm(StrAndUnicode): self._errors[name] = self.error_class(e.messages) 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. - 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. - if not isinstance(v, ComplexValidator): - continue - try: - v(self.cleaned_data[name], all_values=self.cleaned_data) - except ValidationError, e: - failed = True - error_list = self._errors.setdefault(name, self.error_class()) - if hasattr(e, 'code') and e.code in field.error_messages: - message = field.error_messages[e.code] - if e.params: - message = message % e.params - error_list.append(message) - else: - error_list.extend(e.messages) - if failed: - del self.cleaned_data[name] try: self.cleaned_data = self.clean() except ValidationError, e: diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py index 1260417426..db5100b54f 100644 --- a/tests/modeltests/validation/models.py +++ b/tests/modeltests/validation/models.py @@ -1,7 +1,6 @@ from datetime import datetime from django.core.exceptions import ValidationError -from django.core.validators import ComplexValidator from django.db import models from django.test import TestCase @@ -9,14 +8,6 @@ def validate_answer_to_universe(value): if value != 42: raise ValidationError('This is not the answer to life, universe and everything!', code='not42') -class ValidateFieldNotEqualsOtherField(ComplexValidator): - def __init__(self, other_field): - self.other_field = other_field - - def __call__(self, value, all_values={}, obj=None): - if value == self.get_value(self.other_field, all_values, obj): - raise ValidationError("Must not equal to %r's value" % self.other_field, code='not_equal', params=(self.other_field,)) - class ModelToValidate(models.Model): name = models.CharField(max_length=100) created = models.DateTimeField(default=datetime.now) @@ -24,7 +15,7 @@ class ModelToValidate(models.Model): parent = models.ForeignKey('self', blank=True, null=True) email = models.EmailField(blank=True) url = models.URLField(blank=True) - f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe, ValidateFieldNotEqualsOtherField('number')]) + f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe]) def validate(self): super(ModelToValidate, self).validate() @@ -58,7 +49,7 @@ class CustomMessagesModel(models.Model): other = models.IntegerField(blank=True, null=True) number = models.IntegerField( error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'}, - validators=[validate_answer_to_universe, ValidateFieldNotEqualsOtherField('other')] + validators=[validate_answer_to_universe] ) diff --git a/tests/modeltests/validation/test_custom_messages.py b/tests/modeltests/validation/test_custom_messages.py index e543dbd73f..9a958a0a3f 100644 --- a/tests/modeltests/validation/test_custom_messages.py +++ b/tests/modeltests/validation/test_custom_messages.py @@ -1,11 +1,8 @@ from modeltests.validation import ValidationTestCase - from models import CustomMessagesModel -class CustomMessagesTest(ValidationTestCase): - def test_custom_complex_validator_message(self): - cmm = CustomMessagesModel(number=42, other=42) - self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['other != me']) + +class CustomMessagesTest(ValidationTestCase): def test_custom_simple_validator_message(self): cmm = CustomMessagesModel(number=12) self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['AAARGH']) diff --git a/tests/modeltests/validation/validators.py b/tests/modeltests/validation/validators.py index d54aab6234..d46d0c59d5 100644 --- a/tests/modeltests/validation/validators.py +++ b/tests/modeltests/validation/validators.py @@ -18,19 +18,3 @@ class TestModelsWithValidators(ValidationTestCase): [u'This is not the answer to life, universe and everything!'] ) - def test_custom_complex_validator_raises_error_for_incorrect_value(self): - mtv = ModelToValidate(number=42, name='Some Name', f_with_custom_validator=42) - self.assertFailsValidation(mtv.full_validate, ['f_with_custom_validator']) - self.assertFieldFailsValidationWithMessage( - mtv.full_validate, - 'f_with_custom_validator', - [u"Must not equal to 'number''s value"] - ) - - def test_complex_validator_isnt_run_if_field_doesnt_validate(self): - mtv = ModelToValidate(number=32, name='Some Name', f_with_custom_validator=32) - self.assertFieldFailsValidationWithMessage( - mtv.full_validate, - 'f_with_custom_validator', - [u'This is not the answer to life, universe and everything!'] - ) diff --git a/tests/modeltests/validators/tests.py b/tests/modeltests/validators/tests.py index 331f6f0b61..1108ee83f4 100644 --- a/tests/modeltests/validators/tests.py +++ b/tests/modeltests/validators/tests.py @@ -9,8 +9,7 @@ from django.core.validators import ( validate_integer, validate_email, validate_slug, validate_ipv4_address, validate_comma_separated_integer_list, MaxValueValidator, MinValueValidator, MaxLengthValidator, MinLengthValidator, - RequiredIfOtherFieldBlank, URLValidator, BaseValidator, - RegexValidator, + URLValidator, BaseValidator, RegexValidator, ) now = datetime.now() @@ -153,32 +152,3 @@ for validator, value, expected in SIMPLE_VALIDATORS_VALUES: setattr(TestSimpleValidators, *get_simple_test_func(validator, expected, value, test_counter)) test_counter += 1 -class TestComplexValidators(TestCase): - pass - -COMPLEX_VALIDATORS_VALUES = ( - #(validator, value, all_values, obj, expected), - (RequiredIfOtherFieldBlank('other'), 'given', {'other': 'given'}, None, None), - (RequiredIfOtherFieldBlank('other'), '', {'other': 'given'}, None, None), - (RequiredIfOtherFieldBlank('other'), 'given', {}, None, AssertionError), - (RequiredIfOtherFieldBlank('other'), '', {}, None, AssertionError), - (RequiredIfOtherFieldBlank('other'), '', {'other': ''}, None, ValidationError), -) - -def get_complex_test_func(validator, expected, value, all_values, obj, num): - if isinstance(expected, type) and issubclass(expected, Exception): - test_mask = 'test_%s_raises_error_%d' - def test_func(self): - self.assertRaises(expected, validator, value, all_values=all_values, obj=obj) - else: - test_mask = 'test_%s_%d' - def test_func(self): - self.assertEqual(expected, validator(value, all_values=all_values, obj=obj)) - test_name = test_mask % (validator.__class__.__name__, num) - return test_name, test_func - -test_counter = {} -for validator, value, all_values, obj, expected in COMPLEX_VALIDATORS_VALUES: - num = test_counter[validator.__class__.__name__] = test_counter.setdefault(validator.__class__.__name__, 0) + 1 - setattr(TestComplexValidators, *get_complex_test_func(validator, expected, value, all_values, obj, num)) - diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index e9ae948dfd..db70500909 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -38,7 +38,7 @@ from formsets import tests as formset_tests from media import media_tests from fields import FieldsTests -from validators import TestFormWithValidators, TestFieldWithValidators +from validators import TestFieldWithValidators __test__ = { 'extra_tests': extra_tests, diff --git a/tests/regressiontests/forms/validators.py b/tests/regressiontests/forms/validators.py index becf4e2825..b75a14ee17 100644 --- a/tests/regressiontests/forms/validators.py +++ b/tests/regressiontests/forms/validators.py @@ -4,9 +4,6 @@ from django import forms from django.core import validators from django.core.exceptions import ValidationError -class AlwaysFailingValidator(validators.ComplexValidator): - def __call__(self, value, all_values={}, obj=None): - raise ValidationError('AlwaysFailingValidator') class TestFieldWithValidators(TestCase): def test_all_errors_get_reported(self): @@ -19,16 +16,3 @@ class TestFieldWithValidators(TestCase): except ValidationError, e: self.assertEqual(2, len(e.messages)) -class TestFormWithValidators(TestCase): - def test_all_complex_validators_get_run_even_if_they_fail(self): - class MyForm(forms.Form): - validator_field = forms.CharField( - validators=[ - AlwaysFailingValidator(), - AlwaysFailingValidator(), - ] - ) - form = MyForm({'validator_field': 'some value'}) - self.assertFalse(form.is_valid()) - self.assertEqual(['validator_field'], form.errors.keys()) - self.assertEqual(['AlwaysFailingValidator', 'AlwaysFailingValidator'], form.errors['validator_field'])