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:
Artis Avotins 2016-05-25 12:51:41 +02:00
parent ba08b6b438
commit d1337d5a7c
4 changed files with 58 additions and 0 deletions

View file

@ -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>

View file

@ -4,6 +4,9 @@ CHANGES
master (unreleased)
-------------------
* Fix `InheritanceQuerySet` raising an `AttributeError` exception
under Django 1.9.
2.5 (2016-04-18)
----------------

View file

@ -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:

View file

@ -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):