diff options
| author | Keryn Knight <keryn@kerynknight.com> | 2015-04-30 08:57:30 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-09-07 14:36:39 -0400 |
| commit | 3c5862ccb0fc77418c3b20c21c6b57c40b483464 (patch) | |
| tree | 19be451a3543e00691abc00e8a4be9e92fb584a2 /tests/model_forms | |
| parent | 8e84d9c8440f571c0d11cd5d7c35dcedca46392c (diff) | |
Fixed #24706 -- Made ModelForm._post_clean() handle a ValidationError raised when constructing the model instance.
Thanks Loïc Bistuer for review and advice.
Diffstat (limited to 'tests/model_forms')
| -rw-r--r-- | tests/model_forms/models.py | 21 | ||||
| -rw-r--r-- | tests/model_forms/tests.py | 42 |
2 files changed, 61 insertions, 2 deletions
diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index b68714af4c..d9c08ae9c0 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -453,3 +453,24 @@ class Photo(models.Model): class UUIDPK(models.Model): uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=30) + + +# Models for #24706 +class StrictAssignmentFieldSpecific(models.Model): + title = models.CharField(max_length=30) + _should_error = False + + def __setattr__(self, key, value): + if self._should_error is True: + raise ValidationError(message={key: "Cannot set attribute"}, code='invalid') + super(StrictAssignmentFieldSpecific, self).__setattr__(key, value) + + +class StrictAssignmentAll(models.Model): + title = models.CharField(max_length=30) + _should_error = False + + def __setattr__(self, key, value): + if self._should_error is True: + raise ValidationError(message="Cannot set attribute", code='invalid') + super(StrictAssignmentAll, self).__setattr__(key, value) diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index d118785bd4..76f575ac7b 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -29,8 +29,8 @@ from .models import ( DerivedBook, DerivedPost, Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage, ImprovedArticle, ImprovedArticleWithParentLink, Inventory, Person, Photo, Post, Price, Product, Publication, - PublicationDefaults, Student, StumpJoke, TextFile, Triple, Writer, - WriterProfile, test_images, + PublicationDefaults, StrictAssignmentAll, StrictAssignmentFieldSpecific, + Student, StumpJoke, TextFile, Triple, Writer, WriterProfile, test_images, ) if test_images: @@ -2635,3 +2635,41 @@ class CustomMetaclassTestCase(SimpleTestCase): def test_modelform_factory_metaclass(self): new_cls = modelform_factory(Person, fields="__all__", form=CustomMetaclassForm) self.assertEqual(new_cls.base_fields, {}) + + +class StrictAssignmentTests(TestCase): + """ + Should a model do anything special with __setattr__() or descriptors which + raise a ValidationError, a model form should catch the error (#24706). + """ + + def test_setattr_raises_validation_error_field_specific(self): + """ + A model ValidationError using the dict form should put the error + message into the correct key of form.errors. + """ + form_class = modelform_factory(model=StrictAssignmentFieldSpecific, fields=['title']) + form = form_class(data={'title': 'testing setattr'}, files=None) + # This line turns on the ValidationError; it avoids the model erroring + # when its own __init__() is called when creating form.instance. + form.instance._should_error = True + self.assertFalse(form.is_valid()) + self.assertEqual(form.errors, { + 'title': ['Cannot set attribute', 'This field cannot be blank.'] + }) + + def test_setattr_raises_validation_error_non_field(self): + """ + A model ValidationError not using the dict form should put the error + message into __all__ (i.e. non-field errors) on the form. + """ + form_class = modelform_factory(model=StrictAssignmentAll, fields=['title']) + form = form_class(data={'title': 'testing setattr'}, files=None) + # This line turns on the ValidationError; it avoids the model erroring + # when its own __init__() is called when creating form.instance. + form.instance._should_error = True + self.assertFalse(form.is_valid()) + self.assertEqual(form.errors, { + '__all__': ['Cannot set attribute'], + 'title': ['This field cannot be blank.'] + }) |
