mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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:
		| @@ -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]) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user