2
0
Эх сурвалжийг харах

Fixed #13794 -- Fixed to_field usage in BaseInlineFormSet.

Thanks sebastien at clarisys.fr for the report and gautier
for the patch.
Tim Graham 10 жил өмнө
parent
commit
5e2c4a4bd1

+ 5 - 1
django/forms/models.py

@@ -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

+ 11 - 0
tests/model_formsets_regress/models.py

@@ -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)
 

+ 35 - 1
tests/model_formsets_regress/tests.py

@@ -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):
@@ -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__")