Skip to content

Commit

Permalink
[1.4.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 d29f3b9 commit b445190
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
8 changes: 6 additions & 2 deletions django/forms/models.py
Expand Up @@ -712,8 +712,12 @@ def _construct_form(self, i, **kwargs):
# Remove the foreign key from the form's data # Remove the foreign key from the form's data
form.data[form.add_prefix(self.fk.name)] = None form.data[form.add_prefix(self.fk.name)] = None


# Set the fk value here so that the form can do it's validation. # 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 return form


@classmethod @classmethod
Expand Down
9 changes: 9 additions & 0 deletions tests/regressiontests/model_formsets_regress/models.py
Expand Up @@ -9,6 +9,15 @@ class UserSite(models.Model):
user = models.ForeignKey(User, to_field="username") user = models.ForeignKey(User, to_field="username")
data = models.IntegerField() 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): class Place(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)


Expand Down
36 changes: 35 additions & 1 deletion tests/regressiontests/model_formsets_regress/tests.py
Expand Up @@ -6,7 +6,10 @@
from django.forms.models import modelform_factory, inlineformset_factory, modelformset_factory, BaseModelFormSet from django.forms.models import modelform_factory, inlineformset_factory, modelformset_factory, BaseModelFormSet
from django.test import TestCase from django.test import TestCase


from .models import User, UserSite, Restaurant, Manager, Network, Host from .models import (
User, UserSite, UserProfile, ProfileNetwork, Restaurant, Manager, Network,
Host,
)




class InlineFormsetTests(TestCase): class InlineFormsetTests(TestCase):
Expand Down Expand Up @@ -153,6 +156,37 @@ def test_formset_over_inherited_model(self):
else: else:
self.fail('Errors found on formset:%s' % form_set.errors) 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): def test_formset_with_none_instance(self):
"A formset with instance=None can be created. Regression for #11872" "A formset with instance=None can be created. Regression for #11872"
Form = modelform_factory(User) Form = modelform_factory(User)
Expand Down

0 comments on commit b445190

Please sign in to comment.