summaryrefslogtreecommitdiff
path: root/tests/model_forms
diff options
context:
space:
mode:
authorKeryn Knight <keryn@kerynknight.com>2015-04-30 08:57:30 +0100
committerTim Graham <timograham@gmail.com>2015-09-07 14:36:39 -0400
commit3c5862ccb0fc77418c3b20c21c6b57c40b483464 (patch)
tree19be451a3543e00691abc00e8a4be9e92fb584a2 /tests/model_forms
parent8e84d9c8440f571c0d11cd5d7c35dcedca46392c (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.py21
-rw-r--r--tests/model_forms/tests.py42
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.']
+ })