Fixed #12698. Model.clean() used with a ModelForm no longer causes a KeyError when raising a ValidationError.

Note that previously it was possible to raise a ValidationError in the same place with a message_dict attribute. That behavior was a bug and will no longer have the same behavior.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12402 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2010-02-10 00:34:45 +00:00
parent 4682d693c4
commit 8f4540b2e6
3 changed files with 27 additions and 4 deletions

View File

@ -317,7 +317,7 @@ class BaseModelForm(BaseForm):
try: try:
self.instance.clean() self.instance.clean()
except ValidationError, e: except ValidationError, e:
self._update_errors(e.message_dict) self._update_errors({NON_FIELD_ERRORS: e.messages})
super(BaseModelForm, self)._clean_form() super(BaseModelForm, self)._clean_form()
def validate_unique(self): def validate_unique(self):

View File

@ -1,5 +1,7 @@
import os import os
from django.db import models from django.db import models
from django.core.exceptions import ValidationError
class Person(models.Model): class Person(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
@ -37,3 +39,11 @@ class CustomFileField(models.FileField):
class CustomFF(models.Model): class CustomFF(models.Model):
f = CustomFileField(upload_to='unused', blank=True) f = CustomFileField(upload_to='unused', blank=True)
class RealPerson(models.Model):
name = models.CharField(max_length=100)
def clean(self):
if self.name.lower() == 'anonymous':
raise ValidationError("Please specify a real name.")

View File

@ -6,7 +6,8 @@ from django.forms.models import modelform_factory
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase
from models import Person, Triple, FilePathModel, Article, Publication, CustomFF from models import Person, RealPerson, Triple, FilePathModel, Article, Publication, CustomFF
class ModelMultipleChoiceFieldTests(TestCase): class ModelMultipleChoiceFieldTests(TestCase):
@ -117,7 +118,7 @@ class CFFForm(forms.ModelForm):
class CustomFieldSaveTests(TestCase): class CustomFieldSaveTests(TestCase):
def test_save(self): def test_save(self):
"Regression for #11149: save_form_data should be called only once" "Regression for #11149: save_form_data should be called only once"
# It's enough that the form saves without error -- the custom save routine will # It's enough that the form saves without error -- the custom save routine will
# generate an AssertionError if it is called more than once during save. # generate an AssertionError if it is called more than once during save.
form = CFFForm(data = {'f': None}) form = CFFForm(data = {'f': None})
@ -129,8 +130,20 @@ class ModelChoiceIteratorTests(TestCase):
class Meta: class Meta:
model = Article model = Article
fields = ["publications"] fields = ["publications"]
Publication.objects.create(title="Pravda", Publication.objects.create(title="Pravda",
date_published=date(1991, 8, 22)) date_published=date(1991, 8, 22))
f = Form() f = Form()
self.assertEqual(len(f.fields["publications"].choices), 1) self.assertEqual(len(f.fields["publications"].choices), 1)
class RealPersonForm(forms.ModelForm):
class Meta:
model = RealPerson
class CustomModelFormSaveMethod(TestCase):
def test_string_message(self):
data = {'name': 'anonymous'}
form = RealPersonForm(data)
self.assertEqual(form.is_valid(), False)
self.assertEqual(form.errors['__all__'], ['Please specify a real name.'])