[1.8.x] Fixed #24266 -- Changed get_parent_list to return a list ordered by MRO.
Thanks to Aron Podrigal for the initial patch and Tim for the review.
Backport of 65e005f8cd
from master
This commit is contained in:
parent
dd83bab931
commit
cbcf92e95f
|
@ -12,7 +12,7 @@ from django.db.models.fields.related import ManyToManyField
|
||||||
from django.db.models.fields import AutoField
|
from django.db.models.fields import AutoField
|
||||||
from django.db.models.fields.proxy import OrderWrt
|
from django.db.models.fields.proxy import OrderWrt
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.datastructures import ImmutableList
|
from django.utils.datastructures import ImmutableList, OrderedSet
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
|
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
@ -634,14 +634,14 @@ class Options(object):
|
||||||
|
|
||||||
def get_parent_list(self):
|
def get_parent_list(self):
|
||||||
"""
|
"""
|
||||||
Returns a list of all the ancestor of this model as a list. Useful for
|
Returns all the ancestors of this model as a list ordered by MRO.
|
||||||
determining if something is an ancestor, regardless of lineage.
|
Useful for determining if something is an ancestor, regardless of lineage.
|
||||||
"""
|
"""
|
||||||
result = set()
|
result = OrderedSet(self.parents)
|
||||||
for parent in self.parents:
|
for parent in self.parents:
|
||||||
result.add(parent)
|
for ancestor in parent._meta.get_parent_list():
|
||||||
result.update(parent._meta.get_parent_list())
|
result.add(ancestor)
|
||||||
return result
|
return list(result)
|
||||||
|
|
||||||
def get_ancestor_link(self, ancestor):
|
def get_ancestor_link(self, ancestor):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -118,3 +118,20 @@ class Relating(models.Model):
|
||||||
# ManyToManyField to Person
|
# ManyToManyField to Person
|
||||||
people = models.ManyToManyField(Person, related_name='relating_people')
|
people = models.ManyToManyField(Person, related_name='relating_people')
|
||||||
people_hidden = models.ManyToManyField(Person, related_name='+')
|
people_hidden = models.ManyToManyField(Person, related_name='+')
|
||||||
|
|
||||||
|
|
||||||
|
# ParentListTests models
|
||||||
|
class CommonAncestor(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FirstParent(CommonAncestor):
|
||||||
|
first_ancestor = models.OneToOneField(CommonAncestor, primary_key=True, parent_link=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SecondParent(CommonAncestor):
|
||||||
|
second_ancestor = models.OneToOneField(CommonAncestor, primary_key=True, parent_link=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Child(FirstParent, SecondParent):
|
||||||
|
pass
|
||||||
|
|
|
@ -5,7 +5,10 @@ from django.db.models.fields import related, CharField, Field
|
||||||
from django.db.models.options import IMMUTABLE_WARNING, EMPTY_RELATION_TREE
|
from django.db.models.options import IMMUTABLE_WARNING, EMPTY_RELATION_TREE
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from .models import Relation, AbstractPerson, BasePerson, Person, ProxyPerson, Relating
|
from .models import (
|
||||||
|
Relation, AbstractPerson, BasePerson, Person, ProxyPerson, Relating,
|
||||||
|
CommonAncestor, FirstParent, SecondParent, Child
|
||||||
|
)
|
||||||
from .results import TEST_RESULTS
|
from .results import TEST_RESULTS
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,3 +248,11 @@ class RelationTreeTests(TestCase):
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
self.assertEqual([field.related_query_name() for field in AbstractPerson._meta._relation_tree], [])
|
self.assertEqual([field.related_query_name() for field in AbstractPerson._meta._relation_tree], [])
|
||||||
|
|
||||||
|
|
||||||
|
class ParentListTests(TestCase):
|
||||||
|
def test_get_parent_list(self):
|
||||||
|
self.assertEqual(CommonAncestor._meta.get_parent_list(), [])
|
||||||
|
self.assertEqual(FirstParent._meta.get_parent_list(), [CommonAncestor])
|
||||||
|
self.assertEqual(SecondParent._meta.get_parent_list(), [CommonAncestor])
|
||||||
|
self.assertEqual(Child._meta.get_parent_list(), [FirstParent, SecondParent, CommonAncestor])
|
||||||
|
|
Loading…
Reference in New Issue