Skip to content

Commit

Permalink
[1.2.X] Fixed #13987 -- Ensure that the primary key is set correctly …
Browse files Browse the repository at this point in the history
…for all models that have concrete-abstract-concrete inheritance, not just the first model. Thanks to Aramgutang for the report and patch.

Backport of r15498 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15499 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
freakboy3742 committed Feb 12, 2011
1 parent c775f95 commit 48fe609
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
6 changes: 6 additions & 0 deletions django/db/models/options.py
Expand Up @@ -118,6 +118,12 @@ def _prepare(self, model):
# Promote the first parent link in lieu of adding yet another # Promote the first parent link in lieu of adding yet another
# field. # field.
field = self.parents.value_for_index(0) field = self.parents.value_for_index(0)
# Look for a local field with the same name as the
# first parent link. If a local field has already been
# created, use it instead of promoting the parent
already_created = [fld for fld in self.local_fields if fld.name == field.name]
if already_created:
field = already_created[0]
field.primary_key = True field.primary_key = True
self.setup_pk(field) self.setup_pk(field)
else: else:
Expand Down
17 changes: 17 additions & 0 deletions tests/regressiontests/model_inheritance_regress/models.py
Expand Up @@ -146,3 +146,20 @@ class BachelorParty(AbstractEvent):


class MessyBachelorParty(BachelorParty): class MessyBachelorParty(BachelorParty):
pass pass

# Check concrete -> abstract -> concrete inheritance
class SearchableLocation(models.Model):
keywords = models.CharField(max_length=256)

class Station(SearchableLocation):
name = models.CharField(max_length=128)

class Meta:
abstract = True

class BusStation(Station):
bus_routes = models.CommaSeparatedIntegerField(max_length=128)
inbound = models.BooleanField()

class TrainStation(Station):
zone = models.IntegerField()
24 changes: 22 additions & 2 deletions tests/regressiontests/model_inheritance_regress/tests.py
Expand Up @@ -11,7 +11,7 @@
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent, ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM, SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
Person, BirthdayParty, BachelorParty, MessyBachelorParty, Person, BirthdayParty, BachelorParty, MessyBachelorParty,
InternalCertificationAudit) InternalCertificationAudit, BusStation, TrainStation)




class ModelInheritanceTest(TestCase): class ModelInheritanceTest(TestCase):
Expand Down Expand Up @@ -358,7 +358,7 @@ def test_abstract_base_class_m2m_relation_inheritance(self):
parties = list(p4.bachelorparty_set.all()) parties = list(p4.bachelorparty_set.all())
self.assertEqual(parties, [bachelor, messy_parent]) self.assertEqual(parties, [bachelor, messy_parent])


def test_11369(self): def test_abstract_verbose_name_plural_inheritance(self):
""" """
verbose_name_plural correctly inherited from ABC if inheritance chain verbose_name_plural correctly inherited from ABC if inheritance chain
includes an abstract model. includes an abstract model.
Expand Down Expand Up @@ -386,3 +386,23 @@ def test_inherited_nullable_exclude(self):
], ],
attrgetter("pk") attrgetter("pk")
) )

def test_concrete_abstract_concrete_pk(self):
"""
Primary key set correctly with concrete->abstract->concrete inheritance.
"""
# Regression test for #13987: Primary key is incorrectly determined
# when more than one model has a concrete->abstract->concrete
# inheritance hierarchy.
self.assertEquals(
len([field for field in BusStation._meta.local_fields
if field.primary_key]),
1
)
self.assertEquals(
len([field for field in TrainStation._meta.local_fields
if field.primary_key]),
1
)
self.assertIs(BusStation._meta.pk.model, BusStation)
self.assertIs(TrainStation._meta.pk.model, TrainStation)

0 comments on commit 48fe609

Please sign in to comment.