Fix select_subclasses for Django 1.8.

This commit is contained in:
Carl Meyer 2015-01-27 16:48:06 -07:00
parent 3110794afc
commit 3f9b1cfac8

View file

@ -8,7 +8,7 @@ from django.core.exceptions import ObjectDoesNotExist
try: try:
from django.db.models.constants import LOOKUP_SEP from django.db.models.constants import LOOKUP_SEP
from django.utils.six import string_types from django.utils.six import string_types
except ImportError: # Django < 1.5 except ImportError: # Django < 1.5
from django.db.models.sql.constants import LOOKUP_SEP from django.db.models.sql.constants import LOOKUP_SEP
string_types = (basestring,) string_types = (basestring,)
@ -53,20 +53,18 @@ class InheritanceQuerySetMixin(object):
new_qs.subclasses = subclasses new_qs.subclasses = subclasses
return new_qs return new_qs
def _clone(self, klass=None, setup=False, **kwargs): def _clone(self, klass=None, setup=False, **kwargs):
for name in ['subclasses', '_annotated']: for name in ['subclasses', '_annotated']:
if hasattr(self, name): if hasattr(self, name):
kwargs[name] = getattr(self, name) kwargs[name] = getattr(self, name)
return super(InheritanceQuerySetMixin, self)._clone(klass, setup, **kwargs) return super(InheritanceQuerySetMixin, self)._clone(
klass, setup, **kwargs)
def annotate(self, *args, **kwargs): def annotate(self, *args, **kwargs):
qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs) qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs)
qset._annotated = [a.default_alias for a in args] + list(kwargs.keys()) qset._annotated = [a.default_alias for a in args] + list(kwargs.keys())
return qset return qset
def iterator(self): def iterator(self):
iter = super(InheritanceQuerySetMixin, self).iterator() iter = super(InheritanceQuerySetMixin, self).iterator()
if getattr(self, 'subclasses', False): if getattr(self, 'subclasses', False):
@ -95,7 +93,6 @@ class InheritanceQuerySetMixin(object):
for obj in iter: for obj in iter:
yield obj yield obj
def _get_subclasses_recurse(self, model, levels=None): def _get_subclasses_recurse(self, model, levels=None):
""" """
Given a Model class, find all related objects, exploring children Given a Model class, find all related objects, exploring children
@ -115,11 +112,11 @@ class InheritanceQuerySetMixin(object):
if levels or levels is None: if levels or levels is None:
for subclass in self._get_subclasses_recurse( for subclass in self._get_subclasses_recurse(
rel.field.model, levels=levels): rel.field.model, levels=levels):
subclasses.append(rel.get_accessor_name() + LOOKUP_SEP + subclass) subclasses.append(
rel.get_accessor_name() + LOOKUP_SEP + subclass)
subclasses.append(rel.get_accessor_name()) subclasses.append(rel.get_accessor_name())
return subclasses return subclasses
def _get_ancestors_path(self, model, levels=None): def _get_ancestors_path(self, model, levels=None):
""" """
Serves as an opposite to _get_subclasses_recurse, instead walking from Serves as an opposite to _get_subclasses_recurse, instead walking from
@ -127,23 +124,27 @@ class InheritanceQuerySetMixin(object):
select_related string backwards. select_related string backwards.
""" """
if not issubclass(model, self.model): if not issubclass(model, self.model):
raise ValueError("%r is not a subclass of %r" % (model, self.model)) raise ValueError(
"%r is not a subclass of %r" % (model, self.model))
ancestry = [] ancestry = []
# should be a OneToOneField or None # should be a OneToOneField or None
parent = model._meta.get_ancestor_link(self.model) parent_link = model._meta.get_ancestor_link(self.model)
if levels: if levels:
levels -= 1 levels -= 1
while parent is not None: while parent_link is not None:
ancestry.insert(0, parent.related.get_accessor_name()) ancestry.insert(0, parent_link.related.get_accessor_name())
if levels or levels is None: if levels or levels is None:
parent = parent.related.parent_model._meta.get_ancestor_link( if django.VERSION < (1, 8):
parent_model = parent_link.related.parent_model
else:
parent_model = parent_link.related.model
parent_link = parent_model._meta.get_ancestor_link(
self.model) self.model)
else: else:
parent = None parent_link = None
return LOOKUP_SEP.join(ancestry) return LOOKUP_SEP.join(ancestry)
def _get_sub_obj_recurse(self, obj, s): def _get_sub_obj_recurse(self, obj, s):
rel, _, s = s.partition(LOOKUP_SEP) rel, _, s = s.partition(LOOKUP_SEP)
try: try:
@ -170,6 +171,7 @@ class InheritanceQuerySetMixin(object):
levels = 1 levels = 1
return levels return levels
class InheritanceManagerMixin(object): class InheritanceManagerMixin(object):
use_for_related_fields = True use_for_related_fields = True
@ -188,6 +190,7 @@ class InheritanceManagerMixin(object):
class InheritanceQuerySet(InheritanceQuerySetMixin, QuerySet): class InheritanceQuerySet(InheritanceQuerySetMixin, QuerySet):
pass pass
class InheritanceManager(InheritanceManagerMixin, models.Manager): class InheritanceManager(InheritanceManagerMixin, models.Manager):
pass pass
@ -271,7 +274,8 @@ class PassThroughManagerMixin(object):
@classmethod @classmethod
def for_queryset_class(cls, queryset_cls): def for_queryset_class(cls, queryset_cls):
return create_pass_through_manager_for_queryset_class(cls, queryset_cls) return create_pass_through_manager_for_queryset_class(
cls, queryset_cls)
class PassThroughManager(PassThroughManagerMixin, models.Manager): class PassThroughManager(PassThroughManagerMixin, models.Manager):