From 158b0a28374054b1c3f94a9602b69f93fc980448 Mon Sep 17 00:00:00 2001 From: Claude Paroz 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 ` 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):