mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-03-16 20:00:23 +00:00
Fixed a bug with Django >= 1.9 where values_list was called on
InheritanceQuerySet with `select_subclasses` applied as strings raised AttributeError exception. Adds a new test case `test_dj19_values_list_on_select_subclasses`
This commit is contained in:
parent
ba08b6b438
commit
d1337d5a7c
4 changed files with 58 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ ad-m <github.com/ad-m>
|
|||
Alejandro Varas <alej0varas@gmail.com>
|
||||
Alex Orange <crazycasta@gmail.com>
|
||||
Andy Freeland <andy@andyfreeland.net>
|
||||
Artis Avotins <artis.avotins@gmail.com>
|
||||
Bram Boogaard <b.boogaard@auto-interactive.nl>
|
||||
Carl Meyer <carl@dirtcircle.com>
|
||||
Curtis Maloney <curtis@tinbrain.net>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ CHANGES
|
|||
master (unreleased)
|
||||
-------------------
|
||||
|
||||
* Fix `InheritanceQuerySet` raising an `AttributeError` exception
|
||||
under Django 1.9.
|
||||
|
||||
|
||||
2.5 (2016-04-18)
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -161,6 +161,12 @@ class InheritanceQuerySetMixin(object):
|
|||
|
||||
def _get_sub_obj_recurse(self, obj, s):
|
||||
rel, _, s = s.partition(LOOKUP_SEP)
|
||||
|
||||
# Django 1.9: If a primitive type gets passed to this recursive function,
|
||||
# return None as non-models are not part of inheritance.
|
||||
if not isinstance(obj, models.Model):
|
||||
return None
|
||||
|
||||
try:
|
||||
node = getattr(obj, rel)
|
||||
except ObjectDoesNotExist:
|
||||
|
|
|
|||
|
|
@ -768,6 +768,54 @@ class InheritanceManagerTests(TestCase):
|
|||
self.assertEqual(list(queryset), [{'id': self.child1.pk}])
|
||||
|
||||
|
||||
@skipUnless(django.VERSION >= (1, 9, 0), "test only applies to Django 1.9+")
|
||||
def test_dj19_values_list_on_select_subclasses(self):
|
||||
"""
|
||||
Using `select_subclasses` in conjunction with `values_list()` raised an
|
||||
exception in `_get_sub_obj_recurse()` because the result of `values_list()`
|
||||
is either a `tuple` or primitive objects if `flat=True` is specified,
|
||||
because no type checking was done prior to fetching child nodes.
|
||||
|
||||
Django versions below 1.9 are not affected by this bug.
|
||||
"""
|
||||
|
||||
# Querysets are cast to lists to force immediate evaluation.
|
||||
# No exceptions must be thrown.
|
||||
|
||||
# No argument to select_subclasses
|
||||
objs_1 = list(
|
||||
self.get_manager().
|
||||
select_subclasses().
|
||||
values_list('id')
|
||||
)
|
||||
|
||||
# String argument to select_subclasses
|
||||
objs_2 = list(
|
||||
self.get_manager().
|
||||
select_subclasses(
|
||||
"inheritancemanagertestchild2"
|
||||
).
|
||||
values_list('id')
|
||||
)
|
||||
|
||||
# String argument to select_subclasses
|
||||
objs_3 = list(
|
||||
self.get_manager().
|
||||
select_subclasses(
|
||||
InheritanceManagerTestChild2
|
||||
).
|
||||
values_list('id')
|
||||
)
|
||||
|
||||
assert all((
|
||||
isinstance(objs_1, list),
|
||||
isinstance(objs_2, list),
|
||||
isinstance(objs_3, list),
|
||||
))
|
||||
|
||||
assert objs_1 == objs_2 == objs_3
|
||||
|
||||
|
||||
class InheritanceManagerUsingModelsTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue