1
0
mirror of https://github.com/django/django.git synced 2025-07-07 19:29:12 +00:00

[soc2009/model-validation] Added test for field.blank

We still have to decide what to do with fields that have duplicate errors:
 - required from form
 - blank on model
This change resulted in some tests being rendered as invalid. For
example excluding a required field or doing save_as_new on InlineFormset
with non-existing instance.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@10872 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Honza Král 2009-06-01 15:40:18 +00:00
parent 4d73902653
commit a094bda10a
6 changed files with 45 additions and 34 deletions

View File

@ -134,6 +134,12 @@ class Field(object):
raise exceptions.ValidationError(
ugettext_lazy("This field cannot be null."))
# cannot do if not value because of 0 passed to integer fields
if not self.blank and value in ( None, '' ):
raise exceptions.ValidationError(
ugettext_lazy("This field cannot be blank."))
def clean(self, value, model_instance):
"""
Convert the value's type and wun validation. Validation errors from to_python

View File

@ -242,6 +242,22 @@ class BaseModelForm(BaseForm):
opts = self._meta
self.instance = make_instance(self, self.instance, opts.fields, opts.exclude)
self.validate_unique()
try:
# FIMXE: what to do about duplicate errors? (is required etc.)
self.instance.clean()
except ValidationError, e:
for k, v in e.message_dict.items():
if k != NON_FIELD_ERRORS:
self._errors.setdefault(k, []).extend(v)
# Remove the data from the cleaned_data dict since it was invalid
if k in self.cleaned_data:
del self.cleaned_data[k]
# what about fields that don't validate but aren't present on the form?
if NON_FIELD_ERRORS in e.message_dict:
raise ValidationError(e.message_dict[NON_FIELD_ERRORS])
return self.cleaned_data
def validate_unique(self):

View File

@ -449,9 +449,9 @@ u'third-test'
If you call save() with invalid data, you'll get a ValueError.
>>> f = CategoryForm({'name': '', 'slug': 'not a slug!', 'url': 'foo'})
>>> f.errors['name']
[u'This field is required.']
[u'This field is required.', u'This field cannot be blank.']
>>> f.errors['slug']
[u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]
[u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", u'This field cannot be blank.']
>>> f.cleaned_data
Traceback (most recent call last):
...
@ -555,6 +555,8 @@ inserted as 'initial' data in each Field.
<option value="3">Third test</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li>
>>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': u'1', 'article': 'Hello.'}, instance=art)
>>> f.errors
{}
>>> f.is_valid()
True
>>> test_art = f.save()
@ -1102,16 +1104,6 @@ True
>>> instance.delete()
# Test the non-required FileField
>>> f = TextFileForm(data={'description': u'Assistance'})
>>> f.fields['file'].required = False
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.file
<FieldFile: None>
>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': SimpleUploadedFile('test3.txt', 'hello world')}, instance=instance)
>>> f.is_valid()
True
@ -1390,13 +1382,14 @@ False
>>> form._errors
{'__all__': [u'Price with this Price and Quantity already exists.']}
# this form is never valid because quantity is blank=False
>>> class PriceForm(ModelForm):
... class Meta:
... model = Price
... exclude = ('quantity',)
>>> form = PriceForm({'price': '6.00'})
>>> form.is_valid()
True
False
# Unique & unique together with null values
>>> class BookForm(ModelForm):

View File

@ -543,10 +543,6 @@ This is used in the admin for save_as functionality.
... 'book_set-2-title': '',
... }
>>> formset = AuthorBooksFormSet(data, instance=Author(), save_as_new=True)
>>> formset.is_valid()
True
>>> new_author = Author.objects.create(name='Charles Baudelaire')
>>> formset = AuthorBooksFormSet(data, instance=new_author, save_as_new=True)
>>> [book for book in formset.save() if book.author.pk == new_author.pk]
@ -988,19 +984,6 @@ False
>>> formset._non_form_errors
[u'Please correct the duplicate data for price and quantity, which must be unique.']
# only the price field is specified, this should skip any unique checks since the unique_together is not fulfilled.
# this will fail with a KeyError if broken.
>>> FormSet = modelformset_factory(Price, fields=("price",), extra=2)
>>> data = {
... 'form-TOTAL_FORMS': '2',
... 'form-INITIAL_FORMS': '0',
... 'form-0-price': '24',
... 'form-1-price': '24',
... }
>>> formset = FormSet(data)
>>> formset.is_valid()
True
>>> FormSet = inlineformset_factory(Author, Book, extra=0)
>>> author = Author.objects.order_by('id')[0]
>>> book_ids = author.book_set.values_list('id', flat=True)

View File

@ -18,11 +18,16 @@ class BaseModelValidationTests(TestCase):
def test_missing_required_field_raises_error(self):
mtv = ModelToValidate()
self.assertRaises(ValidationError, mtv.clean)
try:
mtv.clean()
except ValidationError, e:
self.assertEquals(['name', 'number'], sorted(e.message_dict.keys()))
def test_with_correct_value_model_validates(self):
mtv = ModelToValidate(number=10)
mtv = ModelToValidate(number=10, name='Some Name')
self.assertEqual(None, mtv.clean())
def test_custom_validate_method_is_called(self):
mtv = ModelToValidate(number=11)
self.assertRaises(ValidationError, mtv.clean)

View File

@ -133,8 +133,12 @@ class SlugFieldTests(django.test.TestCase):
self.assertEqual(bs.s, 'slug'*50)
class ValidationTest(django.test.TestCase):
def test_charfield_cleans_empty_string(self):
def test_charfield_raises_error_on_empty_string(self):
f = models.CharField()
self.assertRaises(ValidationError, f.clean, "", None)
def test_charfield_cleans_empty_string_when_blank_true(self):
f = models.CharField(blank=True)
self.assertEqual('', f.clean('', None))
def test_integerfield_cleans_valid_string(self):
@ -153,8 +157,12 @@ class ValidationTest(django.test.TestCase):
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)
def test_nullable_integerfield_raises_error_with_blank_false(self):
f = models.IntegerField(null=True, blank=False)
self.assertRaises(ValidationError, f.clean, None, None)
def test_nullable_integerfield_cleans_none_on_null_and_blank_true(self):
f = models.IntegerField(null=True, blank=True)
self.assertEqual(None, f.clean(None, None))
def test_integerfield_raises_error_on_empty_input(self):