Kaydet (Commit) 163a34ce authored tarafından Loic Bistuer's avatar Loic Bistuer Kaydeden (comit) Anssi Kääriäinen

Fixed #20883 -- Made model inheritance find parent links in abstract parents

üst dcdc579d
......@@ -184,10 +184,21 @@ class ModelBase(type):
else:
new_class._meta.concrete_model = new_class
# Do the appropriate setup for any model parents.
o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
if isinstance(f, OneToOneField)])
# Collect the parent links for multi-table inheritance.
parent_links = {}
for base in reversed([new_class] + parents):
# Conceptually equivalent to `if base is Model`.
if not hasattr(base, '_meta'):
continue
# Skip concrete parent classes.
if base != new_class and not base._meta.abstract:
continue
# Locate OneToOneField instances.
for field in base._meta.local_fields:
if isinstance(field, OneToOneField):
parent_links[field.rel.to] = field
# Do the appropriate setup for any model parents.
for base in parents:
original_base = base
if not hasattr(base, '_meta'):
......@@ -208,8 +219,8 @@ class ModelBase(type):
if not base._meta.abstract:
# Concrete classes...
base = base._meta.concrete_model
if base in o2o_map:
field = o2o_map[base]
if base in parent_links:
field = parent_links[base]
elif not is_proxy:
attr_name = '%s_ptr' % base._meta.model_name
field = OneToOneField(base, name=attr_name,
......
......@@ -142,6 +142,9 @@ Minor features
the file system permissions of directories created during file upload, like
:setting:`FILE_UPLOAD_PERMISSIONS` does for the files themselves.
* Explicit :class:`~django.db.models.OneToOneField` for
:ref:`multi-table-inheritance` are now discovered in abstract classes.
Backwards incompatible changes in 1.7
=====================================
......
......@@ -50,6 +50,19 @@ class ParkingLot3(Place):
primary_key = models.AutoField(primary_key=True)
parent = models.OneToOneField(Place, parent_link=True)
class ParkingLot4(models.Model):
# Test parent_link connector can be discovered in abstract classes.
parent = models.OneToOneField(Place, parent_link=True)
class Meta:
abstract = True
class ParkingLot4A(ParkingLot4, Place):
pass
class ParkingLot4B(Place, ParkingLot4):
pass
class Supplier(models.Model):
restaurant = models.ForeignKey(Restaurant)
......
......@@ -14,7 +14,8 @@ from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
Person, BirthdayParty, BachelorParty, MessyBachelorParty,
InternalCertificationAudit, BusStation, TrainStation, User, Profile)
InternalCertificationAudit, BusStation, TrainStation, User, Profile,
ParkingLot4A, ParkingLot4B)
class ModelInheritanceTest(TestCase):
......@@ -311,6 +312,19 @@ class ModelInheritanceTest(TestCase):
ParkingLot3._meta.get_ancestor_link(Place).name,
"parent")
def test_use_explicit_o2o_to_parent_from_abstract_model(self):
self.assertEqual(ParkingLot4A._meta.pk.name, "parent")
ParkingLot4A.objects.create(
name="Parking4A",
address='21 Jump Street',
)
self.assertEqual(ParkingLot4B._meta.pk.name, "parent")
ParkingLot4A.objects.create(
name="Parking4B",
address='21 Jump Street',
)
def test_all_fields_from_abstract_base_class(self):
"""
Regression tests for #7588
......
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