mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-03-17 04:10:24 +00:00
Fix bug with child/grandchild select_subclasses in Django 1.6+; thanks Keryn Knight.
This commit is contained in:
parent
8bead336a7
commit
4b6a800050
4 changed files with 39 additions and 4 deletions
|
|
@ -4,6 +4,10 @@ CHANGES
|
|||
master (unreleased)
|
||||
-------------------
|
||||
|
||||
* Fix bug in `InheritanceManager` with grandchild classes on Django 1.6+;
|
||||
`select_subclasses('child', 'child__grandchild')` would only ever get to the
|
||||
child class. Thanks Keryn Knight for report and proposed fix.
|
||||
|
||||
|
||||
1.5.0 (2013.08.29)
|
||||
------------------
|
||||
|
|
|
|||
|
|
@ -46,9 +46,12 @@ class InheritanceQuerySet(QuerySet):
|
|||
def iterator(self):
|
||||
iter = super(InheritanceQuerySet, self).iterator()
|
||||
if getattr(self, 'subclasses', False):
|
||||
# sort the subclass names longest first,
|
||||
# so with 'a' and 'a__b' it goes as deep as possible
|
||||
subclasses = sorted(self.subclasses, key=len, reverse=True)
|
||||
for obj in iter:
|
||||
sub_obj = None
|
||||
for s in self.subclasses:
|
||||
for s in subclasses:
|
||||
sub_obj = self._get_sub_obj_recurse(obj, s)
|
||||
if sub_obj:
|
||||
break
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from model_utils.models import TimeStampedModel, StatusModel, TimeFramedModel
|
||||
|
|
@ -15,6 +18,7 @@ class InheritanceManagerTestRelated(models.Model):
|
|||
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class InheritanceManagerTestParent(models.Model):
|
||||
# FileField is just a handy descriptor-using field. Refs #6.
|
||||
non_related_field_using_descriptor = models.FileField(upload_to="test")
|
||||
|
|
@ -24,11 +28,17 @@ class InheritanceManagerTestParent(models.Model):
|
|||
objects = InheritanceManager()
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%s)" % (
|
||||
self.__class__.__name__[len('InheritanceManagerTest'):],
|
||||
self.pk,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class InheritanceManagerTestChild1(InheritanceManagerTestParent):
|
||||
non_related_field_using_descriptor_2 = models.FileField(upload_to="test")
|
||||
normal_field_2 = models.TextField()
|
||||
pass
|
||||
|
||||
|
||||
class InheritanceManagerTestGrandChild1(InheritanceManagerTestChild1):
|
||||
|
|
|
|||
|
|
@ -542,8 +542,26 @@ class InheritanceManagerTests(TestCase):
|
|||
self.assertEqual(
|
||||
set(
|
||||
self.get_manager().select_subclasses(
|
||||
"inheritancemanagertestchild1__"
|
||||
"inheritancemanagertestgrandchild1"
|
||||
"inheritancemanagertestchild1__inheritancemanagertestgrandchild1"
|
||||
)
|
||||
),
|
||||
children,
|
||||
)
|
||||
|
||||
|
||||
@skipUnless(django.VERSION >= (1, 6, 0), "test only applies to Django 1.6+")
|
||||
def test_children_and_grandchildren(self):
|
||||
children = set([
|
||||
self.child1,
|
||||
InheritanceManagerTestParent(pk=self.child2.pk),
|
||||
self.grandchild1,
|
||||
InheritanceManagerTestChild1(pk=self.grandchild1_2.pk),
|
||||
])
|
||||
self.assertEqual(
|
||||
set(
|
||||
self.get_manager().select_subclasses(
|
||||
"inheritancemanagertestchild1",
|
||||
"inheritancemanagertestchild1__inheritancemanagertestgrandchild1"
|
||||
)
|
||||
),
|
||||
children,
|
||||
|
|
|
|||
Loading…
Reference in a new issue