Loading django/forms/models.py +5 −1 Original line number Diff line number Diff line Loading @@ -876,7 +876,11 @@ class BaseInlineFormSet(BaseModelFormSet): form.data[form.add_prefix(self.fk.name)] = None # Set the fk value here so that the form can do its validation. setattr(form.instance, self.fk.get_attname(), self.instance.pk) fk_value = self.instance.pk if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name: fk_value = getattr(self.instance, self.fk.rel.field_name) fk_value = getattr(fk_value, 'pk', fk_value) setattr(form.instance, self.fk.get_attname(), fk_value) return form @classmethod Loading tests/model_formsets_regress/models.py +11 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,17 @@ class UserSite(models.Model): data = models.IntegerField() class UserProfile(models.Model): user = models.ForeignKey(User, unique=True, to_field="username") about = models.TextField() class ProfileNetwork(models.Model): profile = models.ForeignKey(UserProfile, to_field="user") network = models.IntegerField() identifier = models.IntegerField() class Place(models.Model): name = models.CharField(max_length=50) Loading tests/model_formsets_regress/tests.py +35 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,10 @@ from django.forms.models import modelform_factory, inlineformset_factory, modelf from django.test import TestCase from django.utils import six from .models import User, UserSite, Restaurant, Manager, Network, Host from .models import ( User, UserSite, UserProfile, ProfileNetwork, Restaurant, Manager, Network, Host, ) class InlineFormsetTests(TestCase): Loading Loading @@ -154,6 +157,37 @@ class InlineFormsetTests(TestCase): else: self.fail('Errors found on formset:%s' % form_set.errors) def test_inline_model_with_to_field(self): """ #13794 --- An inline model with a to_field of a formset with instance has working relations. """ FormSet = inlineformset_factory(User, UserSite, exclude=('is_superuser',)) user = User.objects.create(username="guido", serial=1337) UserSite.objects.create(user=user, data=10) formset = FormSet(instance=user) # Testing the inline model's relation self.assertEqual(formset[0].instance.user_id, "guido") def test_inline_model_with_to_field_to_rel(self): """ #13794 --- An inline model with a to_field to a related field of a formset with instance has working relations. """ FormSet = inlineformset_factory(UserProfile, ProfileNetwork, exclude=[]) user = User.objects.create(username="guido", serial=1337, pk=1) self.assertEqual(user.pk, 1) profile = UserProfile.objects.create(user=user, about="about", pk=2) self.assertEqual(profile.pk, 2) ProfileNetwork.objects.create(profile=profile, network=10, identifier=10) formset = FormSet(instance=profile) # Testing the inline model's relation self.assertEqual(formset[0].instance.profile_id, 1) def test_formset_with_none_instance(self): "A formset with instance=None can be created. Regression for #11872" Form = modelform_factory(User, fields="__all__") Loading Loading
django/forms/models.py +5 −1 Original line number Diff line number Diff line Loading @@ -876,7 +876,11 @@ class BaseInlineFormSet(BaseModelFormSet): form.data[form.add_prefix(self.fk.name)] = None # Set the fk value here so that the form can do its validation. setattr(form.instance, self.fk.get_attname(), self.instance.pk) fk_value = self.instance.pk if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name: fk_value = getattr(self.instance, self.fk.rel.field_name) fk_value = getattr(fk_value, 'pk', fk_value) setattr(form.instance, self.fk.get_attname(), fk_value) return form @classmethod Loading
tests/model_formsets_regress/models.py +11 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,17 @@ class UserSite(models.Model): data = models.IntegerField() class UserProfile(models.Model): user = models.ForeignKey(User, unique=True, to_field="username") about = models.TextField() class ProfileNetwork(models.Model): profile = models.ForeignKey(UserProfile, to_field="user") network = models.IntegerField() identifier = models.IntegerField() class Place(models.Model): name = models.CharField(max_length=50) Loading
tests/model_formsets_regress/tests.py +35 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,10 @@ from django.forms.models import modelform_factory, inlineformset_factory, modelf from django.test import TestCase from django.utils import six from .models import User, UserSite, Restaurant, Manager, Network, Host from .models import ( User, UserSite, UserProfile, ProfileNetwork, Restaurant, Manager, Network, Host, ) class InlineFormsetTests(TestCase): Loading Loading @@ -154,6 +157,37 @@ class InlineFormsetTests(TestCase): else: self.fail('Errors found on formset:%s' % form_set.errors) def test_inline_model_with_to_field(self): """ #13794 --- An inline model with a to_field of a formset with instance has working relations. """ FormSet = inlineformset_factory(User, UserSite, exclude=('is_superuser',)) user = User.objects.create(username="guido", serial=1337) UserSite.objects.create(user=user, data=10) formset = FormSet(instance=user) # Testing the inline model's relation self.assertEqual(formset[0].instance.user_id, "guido") def test_inline_model_with_to_field_to_rel(self): """ #13794 --- An inline model with a to_field to a related field of a formset with instance has working relations. """ FormSet = inlineformset_factory(UserProfile, ProfileNetwork, exclude=[]) user = User.objects.create(username="guido", serial=1337, pk=1) self.assertEqual(user.pk, 1) profile = UserProfile.objects.create(user=user, about="about", pk=2) self.assertEqual(profile.pk, 2) ProfileNetwork.objects.create(profile=profile, network=10, identifier=10) formset = FormSet(instance=profile) # Testing the inline model's relation self.assertEqual(formset[0].instance.profile_id, 1) def test_formset_with_none_instance(self): "A formset with instance=None can be created. Regression for #11872" Form = modelform_factory(User, fields="__all__") Loading