From 158b0a28374054b1c3f94a9602b69f93fc980448 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Sat, 19 Sep 2015 14:23:55 +0200
Subject: [PATCH] [1.8.x] Fixed #25431 -- Readded inline foreign keys to
 modelformset instances

Too much field exclusions in form's construct_instance() in _post_clean()
could lead to some unexpected missing ForeignKey values.
Fixes a regression from 45e049937. Refs #13776.

Backport of 65a1055a3 from master.
---
 django/forms/models.py         | 14 +++++---------
 docs/releases/1.8.5.txt        |  3 +++
 tests/model_formsets/models.py |  4 ++++
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/django/forms/models.py b/django/forms/models.py
index 08a3697cc1..2137e9f4a6 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -405,10 +405,11 @@ class BaseModelForm(BaseForm):
         opts = self._meta
 
         exclude = self._get_validation_exclusions()
-        # a subset of `exclude` which won't have the InlineForeignKeyField
-        # if we're adding a new object since that value doesn't exist
-        # until after the new instance is saved to the database.
-        construct_instance_exclude = list(exclude)
+
+        try:
+            self.instance = construct_instance(self, self.instance, opts.fields, exclude)
+        except ValidationError as e:
+            self._update_errors(e)
 
         # Foreign Keys being used to represent inline relationships
         # are excluded from basic field value validation. This is for two
@@ -419,13 +420,8 @@ class BaseModelForm(BaseForm):
         # so this can't be part of _get_validation_exclusions().
         for name, field in self.fields.items():
             if isinstance(field, InlineForeignKeyField):
-                if self.cleaned_data.get(name) is not None and self.cleaned_data[name]._state.adding:
-                    construct_instance_exclude.append(name)
                 exclude.append(name)
 
-        # Update the model instance with self.cleaned_data.
-        self.instance = construct_instance(self, self.instance, opts.fields, construct_instance_exclude)
-
         try:
             self.instance.full_clean(exclude=exclude, validate_unique=False)
         except ValidationError as e:
diff --git a/docs/releases/1.8.5.txt b/docs/releases/1.8.5.txt
index ce03577cde..9cdd802057 100644
--- a/docs/releases/1.8.5.txt
+++ b/docs/releases/1.8.5.txt
@@ -43,3 +43,6 @@ Bugfixes
 * Moved the :ref:`unsaved model instance assignment data loss check
   <unsaved-model-instance-check-18>` on reverse relations to ``Model.save()``
   (:ticket:`25160`).
+
+* Readded inline foreign keys to form instances when validating model formsets
+  (:ticket:`25431`).
diff --git a/tests/model_formsets/models.py b/tests/model_formsets/models.py
index 18b2525738..e30c063bc9 100644
--- a/tests/model_formsets/models.py
+++ b/tests/model_formsets/models.py
@@ -37,6 +37,10 @@ class Book(models.Model):
     def __str__(self):
         return self.title
 
+    def clean(self):
+        # Ensure author is always accessible in clean method
+        assert self.author.name is not None
+
 
 @python_2_unicode_compatible
 class BookWithCustomPK(models.Model):