Fixed #12960. The return value of ModelForm.clean() is now applied to the model. Thanks for the report, krejcik.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12690 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a2c4ad1dab
commit
b88f969789
|
@ -265,6 +265,7 @@ class BaseForm(StrAndUnicode):
|
|||
return
|
||||
self._clean_fields()
|
||||
self._clean_form()
|
||||
self._post_clean()
|
||||
if self._errors:
|
||||
delattr(self, 'cleaned_data')
|
||||
|
||||
|
@ -295,6 +296,13 @@ class BaseForm(StrAndUnicode):
|
|||
except ValidationError, e:
|
||||
self._errors[NON_FIELD_ERRORS] = self.error_class(e.messages)
|
||||
|
||||
def _post_clean(self):
|
||||
"""
|
||||
An internal hook for performing additional cleaning after form cleaning
|
||||
is complete. Used for model validation in model forms.
|
||||
"""
|
||||
pass
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Hook for doing any extra form-wide cleaning after Field.clean() been
|
||||
|
|
|
@ -245,6 +245,10 @@ class BaseModelForm(BaseForm):
|
|||
# if initial was provided, it should override the values from instance
|
||||
if initial is not None:
|
||||
object_data.update(initial)
|
||||
# self._validate_unique will be set to True by BaseModelForm.clean().
|
||||
# It is False by default so overriding self.clean() and failing to call
|
||||
# super will stop validate_unique from being called.
|
||||
self._validate_unique = False
|
||||
super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data,
|
||||
error_class, label_suffix, empty_permitted)
|
||||
|
||||
|
@ -299,34 +303,31 @@ class BaseModelForm(BaseForm):
|
|||
return exclude
|
||||
|
||||
def clean(self):
|
||||
self.validate_unique()
|
||||
self._validate_unique = True
|
||||
return self.cleaned_data
|
||||
|
||||
def _clean_fields(self):
|
||||
"""
|
||||
Cleans the form fields, constructs the instance, then cleans the model
|
||||
fields.
|
||||
"""
|
||||
super(BaseModelForm, self)._clean_fields()
|
||||
opts = self._meta
|
||||
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
|
||||
def _post_clean(self):
|
||||
exclude = self._get_validation_exclusions()
|
||||
opts = self._meta
|
||||
|
||||
# Update the model instance with self.cleaned_data.
|
||||
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
|
||||
|
||||
# Clean the model instance's fields.
|
||||
try:
|
||||
self.instance.clean_fields(exclude=exclude)
|
||||
except ValidationError, e:
|
||||
self._update_errors(e.message_dict)
|
||||
|
||||
def _clean_form(self):
|
||||
"""
|
||||
Runs the instance's clean method, then the form's. This is becuase the
|
||||
form will run validate_unique() by default, and we should run the
|
||||
model's clean method first.
|
||||
"""
|
||||
# Call the model instance's clean method.
|
||||
try:
|
||||
self.instance.clean()
|
||||
except ValidationError, e:
|
||||
self._update_errors({NON_FIELD_ERRORS: e.messages})
|
||||
super(BaseModelForm, self)._clean_form()
|
||||
|
||||
# Validate uniqueness if needed.
|
||||
if self._validate_unique:
|
||||
self.validate_unique()
|
||||
|
||||
def validate_unique(self):
|
||||
"""
|
||||
|
|
|
@ -72,6 +72,26 @@ class OverrideCleanTests(TestCase):
|
|||
# by form.full_clean().
|
||||
self.assertEquals(form.instance.left, 1)
|
||||
|
||||
# Regression test for #12960.
|
||||
# Make sure the cleaned_data returned from ModelForm.clean() is applied to the
|
||||
# model instance.
|
||||
|
||||
class PublicationForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
print self.cleaned_data
|
||||
self.cleaned_data['title'] = self.cleaned_data['title'].upper()
|
||||
return self.cleaned_data
|
||||
|
||||
class Meta:
|
||||
model = Publication
|
||||
|
||||
class ModelFormCleanTest(TestCase):
|
||||
def test_model_form_clean_applies_to_model(self):
|
||||
data = {'title': 'test', 'date_published': '2010-2-25'}
|
||||
form = PublicationForm(data)
|
||||
publication = form.save()
|
||||
self.assertEqual(publication.title, 'TEST')
|
||||
|
||||
class FPForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = FilePathModel
|
||||
|
|
Loading…
Reference in New Issue