1
0
mirror of https://github.com/django/django.git synced 2025-07-06 18:59:13 +00:00

[soc2009/model-validation] Removed the ComplexValidator code in preparation for merging this branch into trunk. It will likely come back in some other form sometime after the merge.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@12078 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2010-01-04 02:16:36 +00:00
parent 556132f75b
commit a54ed5ad1e
11 changed files with 26 additions and 175 deletions

View File

@ -135,26 +135,3 @@ class MaxLengthValidator(BaseValidator):
message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).') message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')
code = 'max_length' 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)

View File

@ -799,26 +799,6 @@ class Model(object):
except ValidationError, e: except ValidationError, e:
errors[f.name] = e.messages 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 # Form.clean() is run even if other validation fails, so do the
# same with Model.validate() for consistency. # same with Model.validate() for consistency.
try: try:

View File

@ -176,19 +176,16 @@ class Field(object):
errors = [] errors = []
for v in self.validators: for v in self.validators:
# Don't run complex validators since they need the model instance try:
# and must therefore be run on the model level. v(value)
if not isinstance(v, validators.ComplexValidator): except exceptions.ValidationError, e:
try: if hasattr(e, 'code') and e.code in self.error_messages:
v(value) message = self.error_messages[e.code]
except exceptions.ValidationError, e: if e.params:
if hasattr(e, 'code') and e.code in self.error_messages: message = message % e.params
message = self.error_messages[e.code] errors.append(message)
if e.params: else:
message = message % e.params errors.extend(e.messages)
errors.append(message)
else:
errors.extend(e.messages)
if errors: if errors:
raise exceptions.ValidationError(errors) raise exceptions.ValidationError(errors)

View File

@ -130,19 +130,16 @@ class Field(object):
return return
errors = [] errors = []
for v in self.validators: for v in self.validators:
# don't run complex validators since they need all_values try:
# and must therefore be run on the form level v(value)
if not isinstance(v, validators.ComplexValidator): except ValidationError, e:
try: if hasattr(e, 'code') and e.code in self.error_messages:
v(value) message = self.error_messages[e.code]
except ValidationError, e: if e.params:
if hasattr(e, 'code') and e.code in self.error_messages: message = message % e.params
message = self.error_messages[e.code] errors.append(message)
if e.params: else:
message = message % e.params errors.extend(e.messages)
errors.append(message)
else:
errors.extend(e.messages)
if errors: if errors:
raise ValidationError(errors) raise ValidationError(errors)

View File

@ -3,7 +3,6 @@ Form classes
""" """
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import ComplexValidator
from django.utils.copycompat import deepcopy from django.utils.copycompat import deepcopy
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.html import conditional_escape from django.utils.html import conditional_escape
@ -283,31 +282,6 @@ class BaseForm(StrAndUnicode):
self._errors[name] = self.error_class(e.messages) self._errors[name] = self.error_class(e.messages)
if name in self.cleaned_data: if name in self.cleaned_data:
del self.cleaned_data[name] 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: try:
self.cleaned_data = self.clean() self.cleaned_data = self.clean()
except ValidationError, e: except ValidationError, e:

View File

@ -1,7 +1,6 @@
from datetime import datetime from datetime import datetime
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import ComplexValidator
from django.db import models from django.db import models
from django.test import TestCase from django.test import TestCase
@ -9,14 +8,6 @@ def validate_answer_to_universe(value):
if value != 42: if value != 42:
raise ValidationError('This is not the answer to life, universe and everything!', code='not42') 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): class ModelToValidate(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
created = models.DateTimeField(default=datetime.now) created = models.DateTimeField(default=datetime.now)
@ -24,7 +15,7 @@ class ModelToValidate(models.Model):
parent = models.ForeignKey('self', blank=True, null=True) parent = models.ForeignKey('self', blank=True, null=True)
email = models.EmailField(blank=True) email = models.EmailField(blank=True)
url = models.URLField(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): def validate(self):
super(ModelToValidate, self).validate() super(ModelToValidate, self).validate()
@ -58,7 +49,7 @@ class CustomMessagesModel(models.Model):
other = models.IntegerField(blank=True, null=True) other = models.IntegerField(blank=True, null=True)
number = models.IntegerField( number = models.IntegerField(
error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'}, error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'},
validators=[validate_answer_to_universe, ValidateFieldNotEqualsOtherField('other')] validators=[validate_answer_to_universe]
) )

View File

@ -1,11 +1,8 @@
from modeltests.validation import ValidationTestCase from modeltests.validation import ValidationTestCase
from models import CustomMessagesModel 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): def test_custom_simple_validator_message(self):
cmm = CustomMessagesModel(number=12) cmm = CustomMessagesModel(number=12)
self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['AAARGH']) self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['AAARGH'])

View File

@ -18,19 +18,3 @@ class TestModelsWithValidators(ValidationTestCase):
[u'This is not the answer to life, universe and everything!'] [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!']
)

View File

@ -9,8 +9,7 @@ from django.core.validators import (
validate_integer, validate_email, validate_slug, validate_ipv4_address, validate_integer, validate_email, validate_slug, validate_ipv4_address,
validate_comma_separated_integer_list, MaxValueValidator, validate_comma_separated_integer_list, MaxValueValidator,
MinValueValidator, MaxLengthValidator, MinLengthValidator, MinValueValidator, MaxLengthValidator, MinLengthValidator,
RequiredIfOtherFieldBlank, URLValidator, BaseValidator, URLValidator, BaseValidator, RegexValidator,
RegexValidator,
) )
now = datetime.now() 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)) setattr(TestSimpleValidators, *get_simple_test_func(validator, expected, value, test_counter))
test_counter += 1 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))

View File

@ -38,7 +38,7 @@ from formsets import tests as formset_tests
from media import media_tests from media import media_tests
from fields import FieldsTests from fields import FieldsTests
from validators import TestFormWithValidators, TestFieldWithValidators from validators import TestFieldWithValidators
__test__ = { __test__ = {
'extra_tests': extra_tests, 'extra_tests': extra_tests,

View File

@ -4,9 +4,6 @@ from django import forms
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
class AlwaysFailingValidator(validators.ComplexValidator):
def __call__(self, value, all_values={}, obj=None):
raise ValidationError('AlwaysFailingValidator')
class TestFieldWithValidators(TestCase): class TestFieldWithValidators(TestCase):
def test_all_errors_get_reported(self): def test_all_errors_get_reported(self):
@ -19,16 +16,3 @@ class TestFieldWithValidators(TestCase):
except ValidationError, e: except ValidationError, e:
self.assertEqual(2, len(e.messages)) 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'])