From a3fca05b05551fdd7089e7be49d48c454ea50a84 Mon Sep 17 00:00:00 2001
From: Stanislas Guerra <stanislas.guerra@gmail.com>
Date: Tue, 24 Feb 2015 10:54:05 +0100
Subject: [PATCH] [1.8.x] Fixed #24395 -- Ensured inline ModelsForms have an
 updated related instance.

Backport of 4c2f546b55c029334d22e69bb29db97f9356faa3 from master
---
 django/forms/models.py        |  4 ++++
 tests/model_formsets/tests.py | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/django/forms/models.py b/django/forms/models.py
index 48fe2f4ac2..b8345d8856 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -891,6 +891,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)
diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py
index 2d0380195b..4de4a5597e 100644
--- a/tests/model_formsets/tests.py
+++ b/tests/model_formsets/tests.py
@@ -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'."