Fixed #29981 -- Fixed inline formsets with a OnetoOneField primary key that uses to_field.

This commit is contained in:
Patrik Sletmo 2018-12-11 20:41:21 +01:00 committed by Tim Graham
parent 02c07be95c
commit 14e2b1b065
3 changed files with 25 additions and 4 deletions

View File

@ -958,8 +958,12 @@ class BaseInlineFormSet(BaseModelFormSet):
kwargs = { kwargs = {
'label': getattr(form.fields.get(name), 'label', capfirst(self.fk.verbose_name)) 'label': getattr(form.fields.get(name), 'label', capfirst(self.fk.verbose_name))
} }
if self.fk.remote_field.field_name != self.fk.remote_field.model._meta.pk.name:
kwargs['to_field'] = self.fk.remote_field.field_name # The InlineForeignKeyField assumes that the foreign key relation is
# based on the parent model's pk. If this isn't the case, set to_field
# to correctly resolve the initial form value.
if self.fk.remote_field.field_name != self.fk.remote_field.model._meta.pk.name:
kwargs['to_field'] = self.fk.remote_field.field_name
# If we're adding a new object, ignore a parent's auto-generated key # If we're adding a new object, ignore a parent's auto-generated key
# as it will be regenerated on the save request. # as it will be regenerated on the save request.

View File

@ -16,6 +16,15 @@ class UserProfile(models.Model):
about = models.TextField() about = models.TextField()
class UserPreferences(models.Model):
user = models.OneToOneField(
User, models.CASCADE,
to_field='username',
primary_key=True,
)
favorite_number = models.IntegerField()
class ProfileNetwork(models.Model): class ProfileNetwork(models.Model):
profile = models.ForeignKey(UserProfile, models.CASCADE, to_field="user") profile = models.ForeignKey(UserProfile, models.CASCADE, to_field="user")
network = models.IntegerField() network = models.IntegerField()

View File

@ -8,8 +8,8 @@ from django.forms.utils import ErrorDict, ErrorList
from django.test import TestCase from django.test import TestCase
from .models import ( from .models import (
Host, Manager, Network, ProfileNetwork, Restaurant, User, UserProfile, Host, Manager, Network, ProfileNetwork, Restaurant, User, UserPreferences,
UserSite, UserProfile, UserSite,
) )
@ -171,6 +171,14 @@ class InlineFormsetTests(TestCase):
# Testing the inline model's relation # Testing the inline model's relation
self.assertEqual(formset[0].instance.user_id, "guido") self.assertEqual(formset[0].instance.user_id, "guido")
def test_inline_model_with_primary_to_field(self):
"""An inline model with a OneToOneField with to_field & primary key."""
FormSet = inlineformset_factory(User, UserPreferences, exclude=('is_superuser',))
user = User.objects.create(username='guido', serial=1337)
UserPreferences.objects.create(user=user, favorite_number=10)
formset = FormSet(instance=user)
self.assertEqual(formset[0].fields['user'].initial, 'guido')
def test_inline_model_with_to_field_to_rel(self): def test_inline_model_with_to_field_to_rel(self):
""" """
#13794 --- An inline model with a to_field to a related field of a #13794 --- An inline model with a to_field to a related field of a