Commit b88f9697 authored by Joseph Kocherhans's avatar Joseph Kocherhans
Browse files

Fixed #12960. The return value of ModelForm.clean() is now applied to the...

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
parent a2c4ad1d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+16 −15
Original line number Diff line number Diff line
@@ -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()
    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)
        exclude = self._get_validation_exclusions()

        # 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):
        """
+20 −0
Original line number Diff line number Diff line
@@ -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