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).')
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:
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:

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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]
)

View File

@ -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'])

View File

@ -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!']
)

View File

@ -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))

View File

@ -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,

View File

@ -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'])