﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
27434	Document caveats of raising a ValidationError in Model.clean() for a field not in a model form	Matthias Kestenholz	Matthias Kestenholz	"Example:

{{{
class DictionaryValidationErrorModel(models.Model):
    field1 = models.CharField(max_length=100)
    field2 = models.CharField(max_length=100)
    field3 = models.CharField(max_length=100)

    def clean(self):
        super(DictionaryValidationErrorModel, self).clean()
        raise ValidationError({
            'field1': 'field1 error',
            'field2': 'field2 error',
        })
}}}

{{{
class DictionaryValidationErrorTests(ValidationTestCase):
    def test_default_form(self):
        class ModelForm(forms.ModelForm):
            class Meta:
                model = DictionaryValidationErrorModel
                fields = ('field1', 'field2', 'field3')

        form = ModelForm({
            'field1': '1',
            'field2': '2',
            'field3': '3',
        })
        self.assertFalse(form.is_valid())
        self.assertEqual(set(form.errors.keys()), {'field1', 'field2'})

    def test_crash(self):
        class ModelForm(forms.ModelForm):
            class Meta:
                model = DictionaryValidationErrorModel
                fields = ('field1', 'field3')

        form = ModelForm({
            'field1': '1',
            'field2': '2',
            'field3': '3',
        })
        self.assertFalse(form.is_valid())
        self.assertEqual(set(form.errors.keys()), {'field1', 'field2'})
}}}

The problem I'm seeing is
{{{

======================================================================
ERROR: test_crash (validation.test_validators.DictionaryValidationErrorTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""/usr/lib/python3.5/unittest/case.py"", line 59, in testPartExecutor
    yield
  File ""/usr/lib/python3.5/unittest/case.py"", line 601, in run
    testMethod()
  File ""/home/matthias/Projects/django/tests/validation/test_validators.py"", line 62, in test_crash
    self.assertFalse(form.is_valid())
  File ""/home/matthias/Projects/django/django/forms/forms.py"", line 169, in is_valid
    return self.is_bound and not self.errors
  File ""/home/matthias/Projects/django/django/forms/forms.py"", line 161, in errors
    self.full_clean()
  File ""/home/matthias/Projects/django/django/forms/forms.py"", line 372, in full_clean
    self._post_clean()
  File ""/home/matthias/Projects/django/django/forms/models.py"", line 400, in _post_clean
    self._update_errors(e)
  File ""/home/matthias/Projects/django/django/forms/models.py"", line 374, in _update_errors
    self.add_error(None, errors)
  File ""/home/matthias/Projects/django/django/forms/forms.py"", line 338, in add_error
    ""'%s' has no field named '%s'."" % (self.__class__.__name__, field))
ValueError: 'ModelForm' has no field named 'field2'.
}}}

This might be a thing for me to work on during the sprints. Also, https://github.com/matthiask/django/commit/2d03c38f888262e63c179b57c0c6bd09312f6f99

(Cc:ing Loïc because we discussed this at DUTH on wednesday evening.)
"	Cleanup/optimization	closed	Documentation	dev	Normal	fixed		Loic Bistuer	Accepted	1	0	0	1	0	0
