10000 [1.5.x] Fixed #13794 -- Fixed to_field usage in BaseInlineFormSet. · alex-python/django@4ae68f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4ae68f6

Browse files
timgrahamramiro
authored andcommitted
[1.5.x] Fixed django#13794 -- Fixed to_field usage in BaseInlineFormSet.
Thanks sebastien at clarisys.fr for the report and gautier for the patch. Backport of 5e2c4a4 from master
1 parent ddc715e commit 4ae68f6

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

django/forms/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,11 @@ def _construct_form(self, i, **kwargs):
736736
form.data[form.add_prefix(self.fk.name)] = None
737737

738738
# Set the fk value here so that the form can do its validation.
739-
setattr(form.instance, self.fk.get_attname(), self.instance.pk)
739+
fk_value = self.instance.pk
740+
if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name:
741+
fk_value = getattr(self.instance, self.fk.rel.field_name)
742+
fk_value = getattr(fk_value, 'pk', fk_value)
743+
setattr(form.instance, self.fk.get_attname(), fk_value)
740744
return form
741745

742746
@classmethod

tests/regressiontests/model_formsets_regress/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ class UserSite(models.Model):
1010
user = models.ForeignKey(User, to_field="username")
1111
data = models.IntegerField()
1212

13+
class UserProfile(models.Model):
14+
user = models.ForeignKey(User, unique=True, to_field="username")
15+
about = models.TextField()
16+
17+
class ProfileNetwork(mod 8000 els.Model):
18+
profile = models.ForeignKey(UserProfile, to_field="user")
19+
network = models.IntegerField()
20+
identifier = models.IntegerField()
21+
1322
class Place(models.Model):
1423
name = models.CharField(max_length=50)
1524

tests/regressiontests/model_formsets_regress/tests.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
from django.test import TestCase
88
from django.utils import six
99

10-
from .models import User, UserSite, Restaurant, Manager, Network, Host
10+
from .models import (
11+
User, UserSite, UserProfile, ProfileNetwork, Restaurant, Manager, Network,
12+
Host,
13+
)
1114

1215

1316
class InlineFormsetTests(TestCase):
@@ -154,6 +157,37 @@ def test_formset_over_inherited_model(self):
154157
else:
155158
self.fail('Errors found on formset:%s' % form_set.errors)
156159

160+
def test_inline_model_with_to_field(self):
161+
"""
162+
#13794 --- An inline model with a to_field of a formset with instance
163+
has working relations.
164+
"""
165+
FormSet = inlineformset_factory(User, UserSite, exclude=('is_superuser',))
166+
167+
user = User.objects.create(username="guido", serial=1337)
168+
UserSite.objects.create(user=user, data=10)
169+
formset = FormSet(instance=user)
170+
171+
# Testing the inline model's relation
172+
self.assertEqual(formset[0].instance.user_id, "guido")
173+
174+
def test_inline_model_with_to_field_to_rel(self):
175+
"""
176+
#13794 --- An inline model with a to_field to a related field of a
177+
formset with instance has working relations.
178+
"""
179+
FormSet = inlineformset_factory(UserProfile, ProfileNetwork, exclude=[])
180+
181+
user = User.objects.create(username="guido", serial=1337, pk=1)
182+
self.assertEqual(user.pk, 1)
183+
profile = UserProfile.objects.create(user=user, about="about", pk=2)
184+
self.assertEqual(profile.pk, 2)
185+
ProfileNetwork.objects.create(profile=profile, network=10, identifier=10)
186+
formset = FormSet(instance=profile)
187+
188+
# Testing the inline model's relation
189+
self.assertEqual(formset[0].instance.profile_id, 1)
190+
157191
def test_formset_with_none_instance(self):
158192
"A formset with instance=None can be created. Regression for #11872"
159193
Form = modelform_factory(User)

0 commit comments

Comments
 (0)
0