~turminal/django

026574e03c6b6fd20a45f97b0470afb70e41fda4 — Simon Charette 8 years ago 97c5539
[1.9.x] 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.

Backport of 67cf5efa31acb2916034afb15610b700695dfcb0 from master
3 files changed, 34 insertions(+), 2 deletions(-)

M django/db/models/base.py
M docs/releases/1.9.5.txt
M tests/model_inheritance/tests.py
M django/db/models/base.py => django/db/models/base.py +9 -1
@@ 245,13 245,21 @@ class ModelBase(type):
                    field = None
                new_class._meta.parents[base] = field
            else:
                base_parents = base._meta.parents.copy()

                # .. and abstract ones.
                for field in parent_fields:
                    new_field = copy.deepcopy(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.
                new_class._meta.parents.update(base._meta.parents)
                new_class._meta.parents.update(base_parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

M docs/releases/1.9.5.txt => docs/releases/1.9.5.txt +3 -0
@@ 40,3 40,6 @@ Bugfixes

* Restored the functionality of the admin's ``raw_id_fields`` in
  ``list_editable`` (:ticket:`26387`).

* Fixed a regression with abstract model inheritance and explicit parent links
  (:ticket:`26413`).

M tests/model_inheritance/tests.py => tests/model_inheritance/tests.py +22 -1
@@ 2,9 2,10 @@ from __future__ import unicode_literals

from operator import attrgetter

from django.apps.registry import Apps
from django.core.exceptions import FieldError, ValidationError
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.utils import CaptureQueriesContext
from django.utils import six


@@ 130,6 131,26 @@ class ModelInheritanceTests(TestCase):
        m = MixinModel()
        self.assertEqual(m.other_attr, 1)

    def test_abstract_parent_link(self):
        test_apps = Apps(['model_inheritance'])

        class A(models.Model):
            class Meta:
                apps = test_apps

        class B(A):
            a = models.OneToOneField('A', parent_link=True, on_delete=models.CASCADE)

            class Meta:
                apps = test_apps
                abstract = True

        class C(B):
            class Meta:
                apps = test_apps

        self.assertIs(C._meta.parents[A], C._meta.get_field('a'))


class ModelInheritanceDataTests(TestCase):
    @classmethod