Kaydet (Commit) a50b66da authored tarafından Jason Hoos's avatar Jason Hoos Kaydeden (comit) Tim Graham

Fixed #24958 -- Fixed inline forms using UUID-PK parents with auto-PK children.

üst 0cc39e50
...@@ -929,10 +929,15 @@ class BaseInlineFormSet(BaseModelFormSet): ...@@ -929,10 +929,15 @@ class BaseInlineFormSet(BaseModelFormSet):
if self.fk.remote_field.field_name != self.fk.remote_field.model._meta.pk.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 kwargs['to_field'] = self.fk.remote_field.field_name
# If we're adding a new object, ignore a parent's auto-generated pk # 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.
if self.instance._state.adding and form._meta.model._meta.pk.has_default(): if self.instance._state.adding:
self.instance.pk = None if kwargs.get('to_field') is not None:
to_field = self.instance._meta.get_field(kwargs['to_field'])
else:
to_field = self.instance._meta.pk
if to_field.has_default():
setattr(self.instance, to_field.attname, None)
form.fields[name] = InlineForeignKeyField(self.instance, **kwargs) form.fields[name] = InlineForeignKeyField(self.instance, **kwargs)
......
...@@ -85,3 +85,7 @@ Bugfixes ...@@ -85,3 +85,7 @@ Bugfixes
* Reallowed non-ASCII values for ``ForeignKey.related_name`` on Python 3 by * Reallowed non-ASCII values for ``ForeignKey.related_name`` on Python 3 by
fixing the false positive system check (:ticket:`25016`). fixing the false positive system check (:ticket:`25016`).
* Fixed inline forms that use a parent object that has a ``UUIDField`` primary
key and a child object that has an ``AutoField`` primary key
(:ticket:`24958`).
...@@ -254,3 +254,33 @@ class UUIDPKChild(models.Model): ...@@ -254,3 +254,33 @@ class UUIDPKChild(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
parent = models.ForeignKey(UUIDPKParent) parent = models.ForeignKey(UUIDPKParent)
class ChildWithEditablePK(models.Model):
name = models.CharField(max_length=255, primary_key=True)
parent = models.ForeignKey(UUIDPKParent)
class AutoPKChildOfUUIDPKParent(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey(UUIDPKParent)
class AutoPKParent(models.Model):
name = models.CharField(max_length=255)
class UUIDPKChildOfAutoPKParent(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
parent = models.ForeignKey(AutoPKParent)
class ParentWithUUIDAlternateKey(models.Model):
uuid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=50)
class ChildRelatedViaAK(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey(to=ParentWithUUIDAlternateKey, to_field='uuid')
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from django.test import TestCase from django.test import TestCase
from .models import UUIDPKChild, UUIDPKParent from .models import (
AutoPKChildOfUUIDPKParent, AutoPKParent, ChildRelatedViaAK,
ChildWithEditablePK, ParentWithUUIDAlternateKey, UUIDPKChild,
UUIDPKChildOfAutoPKParent, UUIDPKParent,
)
class InlineFormsetTests(TestCase): class InlineFormsetTests(TestCase):
...@@ -10,6 +14,8 @@ class InlineFormsetTests(TestCase): ...@@ -10,6 +14,8 @@ class InlineFormsetTests(TestCase):
#24377 - If we're adding a new object, a parent's auto-generated pk #24377 - If we're adding a new object, a parent's auto-generated pk
from the model field default should be ignored as it's regenerated on from the model field default should be ignored as it's regenerated on
the save request. the save request.
Tests the case where both the parent and child have a UUID primary key.
""" """
FormSet = inlineformset_factory(UUIDPKParent, UUIDPKChild, fields='__all__') FormSet = inlineformset_factory(UUIDPKParent, UUIDPKChild, fields='__all__')
formset = FormSet() formset = FormSet()
...@@ -30,3 +36,43 @@ class InlineFormsetTests(TestCase): ...@@ -30,3 +36,43 @@ class InlineFormsetTests(TestCase):
'uuidpkchild_set-2-name': '', 'uuidpkchild_set-2-name': '',
}) })
self.assertTrue(formset.is_valid()) self.assertTrue(formset.is_valid())
def test_inlineformset_factory_nulls_default_pks_uuid_parent_auto_child(self):
"""
#24958 - Variant of test_inlineformset_factory_nulls_default_pks for
the case of a parent object with a UUID primary key and a child object
with an AutoField primary key.
"""
FormSet = inlineformset_factory(UUIDPKParent, AutoPKChildOfUUIDPKParent, fields='__all__')
formset = FormSet()
self.assertIsNone(formset.forms[0].fields['parent'].initial)
def test_inlineformset_factory_nulls_default_pks_auto_parent_uuid_child(self):
"""
#24958 - Variant of test_inlineformset_factory_nulls_default_pks for
the case of a parent object with an AutoField primary key and a child
object with a UUID primary key.
"""
FormSet = inlineformset_factory(AutoPKParent, UUIDPKChildOfAutoPKParent, fields='__all__')
formset = FormSet()
self.assertIsNone(formset.forms[0].fields['parent'].initial)
def test_inlineformset_factory_nulls_default_pks_child_editable_pk(self):
"""
#24958 - Variant of test_inlineformset_factory_nulls_default_pks for
the case of a parent object with a UUID primary key and a child
object with an editable natural key for a primary key.
"""
FormSet = inlineformset_factory(UUIDPKParent, ChildWithEditablePK, fields='__all__')
formset = FormSet()
self.assertIsNone(formset.forms[0].fields['parent'].initial)
def test_inlineformset_factory_nulls_default_pks_alternate_key_relation(self):
"""
#24958 - Variant of test_inlineformset_factory_nulls_default_pks for
the case of a parent object with a UUID alternate key and a child
object that relates to that alternate key.
"""
FormSet = inlineformset_factory(ParentWithUUIDAlternateKey, ChildRelatedViaAK, fields='__all__')
formset = FormSet()
self.assertIsNone(formset.forms[0].fields['parent'].initial)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment