diff --git a/django/forms/forms.py b/django/forms/forms.py
index 6f7a8ce..45bbbb4 100644
a
|
b
|
class BaseForm(StrAndUnicode):
|
265 | 265 | return |
266 | 266 | self._clean_fields() |
267 | 267 | self._clean_form() |
| 268 | self._post_clean() |
268 | 269 | if self._errors: |
269 | 270 | delattr(self, 'cleaned_data') |
270 | 271 | |
… |
… |
class BaseForm(StrAndUnicode):
|
295 | 296 | except ValidationError, e: |
296 | 297 | self._errors[NON_FIELD_ERRORS] = self.error_class(e.messages) |
297 | 298 | |
| 299 | def _post_clean(self): |
| 300 | """ |
| 301 | An internal hook for performing additional cleaning after form cleaning |
| 302 | is complete. Used for model validation in model forms. |
| 303 | """ |
| 304 | pass |
| 305 | |
298 | 306 | def clean(self): |
299 | 307 | """ |
300 | 308 | Hook for doing any extra form-wide cleaning after Field.clean() been |
diff --git a/django/forms/models.py b/django/forms/models.py
index 65fe1a7..3c95b4d 100644
a
|
b
|
class BaseModelForm(BaseForm):
|
245 | 245 | # if initial was provided, it should override the values from instance |
246 | 246 | if initial is not None: |
247 | 247 | object_data.update(initial) |
| 248 | # This will be set to True by BaseModelForm.clean(). This makes it so |
| 249 | # it will be set to False if someone overrides that method and doesn't |
| 250 | # call super. Unfortunately the implementation detail of overriding |
| 251 | # clean() to prevent unique valiation was documented. |
| 252 | self._validate_unique = False |
248 | 253 | super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data, |
249 | 254 | error_class, label_suffix, empty_permitted) |
250 | 255 | |
… |
… |
class BaseModelForm(BaseForm):
|
299 | 304 | return exclude |
300 | 305 | |
301 | 306 | def clean(self): |
302 | | self.validate_unique() |
| 307 | # Set self._validate_unique to True so self.validate_unique will be |
| 308 | # called later, and so that overriding this method and failing to call |
| 309 | # super will cause self.validate_unique() to not be called. This is an |
| 310 | # unfortunate hack to keep backwards compatibility for an |
| 311 | # implementation detail that shouldn't have been documented. |
| 312 | self._validate_unique = True |
303 | 313 | return self.cleaned_data |
304 | 314 | |
305 | | def _clean_fields(self): |
306 | | """ |
307 | | Cleans the form fields, constructs the instance, then cleans the model |
308 | | fields. |
309 | | """ |
310 | | super(BaseModelForm, self)._clean_fields() |
| 315 | def _post_clean(self): |
| 316 | exclude = self._get_validation_exclusions() |
311 | 317 | opts = self._meta |
| 318 | |
| 319 | # Update the model instance with self.cleaned_data. |
312 | 320 | self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude) |
313 | | exclude = self._get_validation_exclusions() |
| 321 | |
| 322 | # Clean the model instance's fields. |
314 | 323 | try: |
315 | 324 | self.instance.clean_fields(exclude=exclude) |
316 | 325 | except ValidationError, e: |
317 | 326 | self._update_errors(e.message_dict) |
318 | 327 | |
319 | | def _clean_form(self): |
320 | | """ |
321 | | Runs the instance's clean method, then the form's. This is becuase the |
322 | | form will run validate_unique() by default, and we should run the |
323 | | model's clean method first. |
324 | | """ |
| 328 | # Call the model instance's clean method. |
325 | 329 | try: |
326 | 330 | self.instance.clean() |
327 | 331 | except ValidationError, e: |
328 | 332 | self._update_errors({NON_FIELD_ERRORS: e.messages}) |
329 | | super(BaseModelForm, self)._clean_form() |
| 333 | |
| 334 | # Validate uniqueness if needed. |
| 335 | if self._validate_unique: |
| 336 | self.validate_unique() |
330 | 337 | |
331 | 338 | def validate_unique(self): |
332 | 339 | """ |
diff --git a/tests/regressiontests/model_forms_regress/tests.py b/tests/regressiontests/model_forms_regress/tests.py
index d03e61d..485160a 100644
a
|
b
|
class OverrideCleanTests(TestCase):
|
72 | 72 | # by form.full_clean(). |
73 | 73 | self.assertEquals(form.instance.left, 1) |
74 | 74 | |
| 75 | # Regression test for #12960. |
| 76 | # Make sure the cleaned_data returned from ModelForm.clean() is applied to the |
| 77 | # model instance. |
| 78 | |
| 79 | class PublicationForm(forms.ModelForm): |
| 80 | def clean(self): |
| 81 | print self.cleaned_data |
| 82 | self.cleaned_data['title'] = self.cleaned_data['title'].upper() |
| 83 | return self.cleaned_data |
| 84 | |
| 85 | class Meta: |
| 86 | model = Publication |
| 87 | |
| 88 | class ModelFormCleanTest(TestCase): |
| 89 | def test_model_form_clean_applies_to_model(self): |
| 90 | data = {'title': 'test', 'date_published': '2010-2-25'} |
| 91 | form = PublicationForm(data) |
| 92 | publication = form.save() |
| 93 | self.assertEqual(publication.title, 'TEST') |
| 94 | |
75 | 95 | class FPForm(forms.ModelForm): |
76 | 96 | class Meta: |
77 | 97 | model = FilePathModel |