Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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

…parents
  • Loading branch information...
commit 163a34ce4bc1086b346a52c7271f48d2c207f710 1 parent dcdc579
@loic loic authored akaariai committed
View
21 django/db/models/base.py
@@ -184,10 +184,21 @@ def __new__(cls, name, bases, attrs):
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 @@ def __new__(cls, name, bases, attrs):
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,
View
3  docs/releases/1.7.txt
@@ -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
=====================================
View
13 tests/model_inheritance_regress/models.py
@@ -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)
View
16 tests/model_inheritance_regress/tests.py
@@ -14,7 +14,8 @@
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 @@ def test_use_explicit_o2o_to_parent_as_pk(self):
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
Please sign in to comment.
Something went wrong with that request. Please try again.