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.
This commit is contained in:
parent
281fc03474
commit
65e005f8cd
|
@ -12,7 +12,7 @@ from django.db.models.fields.related import ManyToManyField
|
|||
from django.db.models.fields import AutoField
|
||||
from django.db.models.fields.proxy import OrderWrt
|
||||
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.encoding import force_text, smart_text, python_2_unicode_compatible
|
||||
from django.utils.functional import cached_property
|
||||
|
@ -634,14 +634,14 @@ class Options(object):
|
|||
|
||||
def get_parent_list(self):
|
||||
"""
|
||||
Returns a list of all the ancestor of this model as a list. Useful for
|
||||
determining if something is an ancestor, regardless of lineage.
|
||||
Returns all the ancestors of this model as a list ordered by MRO.
|
||||
Useful for determining if something is an ancestor, regardless of lineage.
|
||||
"""
|
||||
result = set()
|
||||
result = OrderedSet(self.parents)
|
||||
for parent in self.parents:
|
||||
result.add(parent)
|
||||
result.update(parent._meta.get_parent_list())
|
||||
return result
|
||||
for ancestor in parent._meta.get_parent_list():
|
||||
result.add(ancestor)
|
||||
return list(result)
|
||||
|
||||
def get_ancestor_link(self, ancestor):
|
||||
"""
|
||||
|
|
|
@ -118,3 +118,20 @@ class Relating(models.Model):
|
|||
# ManyToManyField to Person
|
||||
people = models.ManyToManyField(Person, related_name='relating_people')
|
||||
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.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
|
||||
|
||||
|
||||
|
@ -245,3 +248,11 @@ class RelationTreeTests(TestCase):
|
|||
])
|
||||
)
|
||||
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