Skip to content

Commit

Permalink
[1.6.x] Fixed #13794 -- Fixed to_field usage in BaseInlineFormSet.
Browse files Browse the repository at this point in the history
Thanks sebastien at clarisys.fr for the report and gautier
for the patch.

Backport of 5e2c4a4 from master
  • Loading branch information
timgraham authored and ramiro committed Jul 14, 2014
1 parent a823a74 commit 6855829
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
6 changes: 5 additions & 1 deletion django/forms/models.py
Expand Up @@ -855,7 +855,11 @@ def _construct_form(self, i, **kwargs):
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
Expand Down
9 changes: 9 additions & 0 deletions tests/model_formsets_regress/models.py
Expand Up @@ -10,6 +10,15 @@ class UserSite(models.Model):
user = models.ForeignKey(User, to_field="username")
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)

Expand Down
36 changes: 35 additions & 1 deletion tests/model_formsets_regress/tests.py
Expand Up @@ -7,7 +7,10 @@
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):
Expand Down Expand Up @@ -154,6 +157,37 @@ def test_formset_over_inherited_model(self):
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__")
Expand Down

0 comments on commit 6855829

Please sign in to comment.