Commit 4c2f546b authored by Stanislas Guerra's avatar Stanislas Guerra Committed by Tim Graham
Browse files

Fixed #24395 -- Ensured inline ModelsForms have an updated related instance.

parent 8e129b42
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -904,6 +904,10 @@ class BaseInlineFormSet(BaseModelFormSet):
        return cls.fk.rel.get_accessor_name(model=cls.model).replace('+', '')

    def save_new(self, form, commit=True):
        # Ensure the latest copy of the related instance is present on each
        # form (it may have been saved after the formset was originally
        # instantiated).
        setattr(form.instance, self.fk.name, self.instance)
        # Use commit=False so we can assign the parent key afterwards, then
        # save the object.
        obj = form.save(commit=False)
+32 −0
Original line number Diff line number Diff line
@@ -819,6 +819,38 @@ class ModelFormsetTest(TestCase):
        formset = AuthorBooksFormSet(data, instance=author, queryset=custom_qs)
        self.assertTrue(formset.is_valid())

    def test_inline_formsets_with_custom_save_method_related_instance(self):
        """
        The ModelForm.save() method should be able to access the related object
        if it exists in the database (#24395).
        """
        class PoemForm2(forms.ModelForm):
            def save(self, commit=True):
                poem = super(PoemForm2, self).save(commit=False)
                poem.name = "%s by %s" % (poem.name, poem.poet.name)
                if commit:
                    poem.save()
                return poem

        PoemFormSet = inlineformset_factory(Poet, Poem, form=PoemForm2, fields="__all__")
        data = {
            'poem_set-TOTAL_FORMS': '1',
            'poem_set-INITIAL_FORMS': '0',
            'poem_set-MAX_NUM_FORMS': '',
            'poem_set-0-name': 'Le Lac',
        }
        poet = Poet()
        formset = PoemFormSet(data=data, instance=poet)
        self.assertTrue(formset.is_valid())

        # The Poet instance is saved after the formset instantiation. This
        # happens in admin's changeform_view() when adding a new object and
        # some inlines in the same request.
        poet.name = 'Lamartine'
        poet.save()
        poem = formset.save()[0]
        self.assertEqual(poem.name, 'Le Lac by Lamartine')

    def test_inline_formsets_with_wrong_fk_name(self):
        """ Regression for #23451 """
        message = "fk_name 'title' is not a ForeignKey to 'model_formsets.Author'."