Commit 48fe6099 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

[1.2.X] Fixed #13987 -- Ensure that the primary key is set correctly for all...

[1.2.X] Fixed #13987 -- Ensure that the primary key is set correctly 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
parent c775f95a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -118,6 +118,12 @@ class Options(object):
                # Promote the first parent link in lieu of adding yet another
                # field.
                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
                self.setup_pk(field)
            else:
+17 −0
Original line number Diff line number Diff line
@@ -146,3 +146,20 @@ class BachelorParty(AbstractEvent):

class MessyBachelorParty(BachelorParty):
    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()
+22 −2
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ from models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
    ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
    SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
    Person, BirthdayParty, BachelorParty, MessyBachelorParty,
    InternalCertificationAudit)
    InternalCertificationAudit, BusStation, TrainStation)


class ModelInheritanceTest(TestCase):
@@ -358,7 +358,7 @@ class ModelInheritanceTest(TestCase):
        parties = list(p4.bachelorparty_set.all())
        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
        includes an abstract model.
@@ -386,3 +386,23 @@ class ModelInheritanceTest(TestCase):
            ],
            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)