mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-05-27 02:53:59 +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)
|
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)
|
1.5.0 (2013.08.29)
|
||||||
------------------
|
------------------
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,12 @@ class InheritanceQuerySet(QuerySet):
|
||||||
def iterator(self):
|
def iterator(self):
|
||||||
iter = super(InheritanceQuerySet, self).iterator()
|
iter = super(InheritanceQuerySet, self).iterator()
|
||||||
if getattr(self, 'subclasses', False):
|
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:
|
for obj in iter:
|
||||||
sub_obj = None
|
sub_obj = None
|
||||||
for s in self.subclasses:
|
for s in subclasses:
|
||||||
sub_obj = self._get_sub_obj_recurse(obj, s)
|
sub_obj = self._get_sub_obj_recurse(obj, s)
|
||||||
if sub_obj:
|
if sub_obj:
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from model_utils.models import TimeStampedModel, StatusModel, TimeFramedModel
|
from model_utils.models import TimeStampedModel, StatusModel, TimeFramedModel
|
||||||
|
|
@ -15,6 +18,7 @@ class InheritanceManagerTestRelated(models.Model):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class InheritanceManagerTestParent(models.Model):
|
class InheritanceManagerTestParent(models.Model):
|
||||||
# FileField is just a handy descriptor-using field. Refs #6.
|
# FileField is just a handy descriptor-using field. Refs #6.
|
||||||
non_related_field_using_descriptor = models.FileField(upload_to="test")
|
non_related_field_using_descriptor = models.FileField(upload_to="test")
|
||||||
|
|
@ -24,11 +28,17 @@ class InheritanceManagerTestParent(models.Model):
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s(%s)" % (
|
||||||
|
self.__class__.__name__[len('InheritanceManagerTest'):],
|
||||||
|
self.pk,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class InheritanceManagerTestChild1(InheritanceManagerTestParent):
|
class InheritanceManagerTestChild1(InheritanceManagerTestParent):
|
||||||
non_related_field_using_descriptor_2 = models.FileField(upload_to="test")
|
non_related_field_using_descriptor_2 = models.FileField(upload_to="test")
|
||||||
normal_field_2 = models.TextField()
|
normal_field_2 = models.TextField()
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InheritanceManagerTestGrandChild1(InheritanceManagerTestChild1):
|
class InheritanceManagerTestGrandChild1(InheritanceManagerTestChild1):
|
||||||
|
|
|
||||||
|
|
@ -542,8 +542,26 @@ class InheritanceManagerTests(TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(
|
set(
|
||||||
self.get_manager().select_subclasses(
|
self.get_manager().select_subclasses(
|
||||||
"inheritancemanagertestchild1__"
|
"inheritancemanagertestchild1__inheritancemanagertestgrandchild1"
|
||||||
"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,
|
children,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue