mirror of https://github.com/django/django.git
Fixed #26413 -- Fixed a regression with abstract model inheritance and explicit parent links.
Thanks Trac alias trkjgrdg for the report and Tim for investigation and review.
This commit is contained in:
parent
0c0e8f0a62
commit
67cf5efa31
|
@ -244,13 +244,21 @@ class ModelBase(type):
|
||||||
field = None
|
field = None
|
||||||
new_class._meta.parents[base] = field
|
new_class._meta.parents[base] = field
|
||||||
else:
|
else:
|
||||||
|
base_parents = base._meta.parents.copy()
|
||||||
|
|
||||||
# .. and abstract ones.
|
# .. and abstract ones.
|
||||||
for field in parent_fields:
|
for field in parent_fields:
|
||||||
new_field = copy.deepcopy(field)
|
new_field = copy.deepcopy(field)
|
||||||
new_class.add_to_class(field.name, new_field)
|
new_class.add_to_class(field.name, new_field)
|
||||||
|
# Replace parent links defined on this base by the new
|
||||||
|
# field as it will be appropriately resolved if required.
|
||||||
|
if field.one_to_one:
|
||||||
|
for parent, parent_link in base_parents.items():
|
||||||
|
if field == parent_link:
|
||||||
|
base_parents[parent] = new_field
|
||||||
|
|
||||||
# Pass any non-abstract parent classes onto child.
|
# Pass any non-abstract parent classes onto child.
|
||||||
new_class._meta.parents.update(base._meta.parents)
|
new_class._meta.parents.update(base_parents)
|
||||||
|
|
||||||
# Inherit managers from the abstract base classes.
|
# Inherit managers from the abstract base classes.
|
||||||
new_class.copy_managers(base._meta.abstract_managers)
|
new_class.copy_managers(base._meta.abstract_managers)
|
||||||
|
|
|
@ -40,3 +40,6 @@ Bugfixes
|
||||||
|
|
||||||
* Restored the functionality of the admin's ``raw_id_fields`` in
|
* Restored the functionality of the admin's ``raw_id_fields`` in
|
||||||
``list_editable`` (:ticket:`26387`).
|
``list_editable`` (:ticket:`26387`).
|
||||||
|
|
||||||
|
* Fixed a regression with abstract model inheritance and explicit parent links
|
||||||
|
(:ticket:`26413`).
|
||||||
|
|
|
@ -4,9 +4,9 @@ from operator import attrgetter
|
||||||
|
|
||||||
from django.core.exceptions import FieldError, ValidationError
|
from django.core.exceptions import FieldError, ValidationError
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.db import connection
|
from django.db import connection, models
|
||||||
from django.test import TestCase, TransactionTestCase
|
from django.test import TestCase, TransactionTestCase
|
||||||
from django.test.utils import CaptureQueriesContext
|
from django.test.utils import CaptureQueriesContext, isolate_apps
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
|
@ -140,6 +140,22 @@ class ModelInheritanceTests(TestCase):
|
||||||
m = MixinModel()
|
m = MixinModel()
|
||||||
self.assertEqual(m.other_attr, 1)
|
self.assertEqual(m.other_attr, 1)
|
||||||
|
|
||||||
|
@isolate_apps('model_inheritance')
|
||||||
|
def test_abstract_parent_link(self):
|
||||||
|
class A(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
a = models.OneToOneField('A', parent_link=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
class C(B):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertIs(C._meta.parents[A], C._meta.get_field('a'))
|
||||||
|
|
||||||
|
|
||||||
class ModelInheritanceDataTests(TestCase):
|
class ModelInheritanceDataTests(TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Reference in New Issue