Inheritance improvments: Select subclasses of foreign relations + get subclass of model fields
mortenthansen opened this issue · 0 comments
mortenthansen commented
Problem
I wanted to do single query SQL selects of foreign key relations that are using Django model inheritance and found the following two improvements helpful.
Let me know what you think.
Code examples
Improvement to InheritanceQuerySet that is able to select inherited fields of foreign key relationship. Note that this works with multi-level inheritance by letting field_name be a tuple of list of names.
`
class InheritanceQuerySet(ModelUtilsInheritanceQuerySet):
def select_field_subclasses(self, field_name):
# Get field name iterable
if isinstance(field_name, str):
field_names = (field_name,)
else:
field_names = field_name
# Lookup model
model = self.model
for field_name in field_names:
field = model._meta.get_field(field_name)
model = field.related_model
# Lookup subclasses
subclasses = self._get_subclasses_recurse(model)
# Construct query
subclasses = ['%s__%s' % ('__'.join(field_names), subclass) for subclass in subclasses]
return self.select_related(*subclasses)
`
Using proper select queries with the above method, subclasses of foreign key relations can be retrieved with the following Model Mixin without touching the database.
`
class InheritanceMixin:
def get_subclass(self):
# Lookup subclasses
helper = InheritanceQuerySetMixin() # hack to re-use private method of mixin
subclasses = helper._get_subclasses_recurse(self.__class__)
# Look for existing subclass
for subclass in subclasses:
try:
return getattr(self, subclass)
except getattr(self.__class__, subclass).RelatedObjectDoesNotExist:
pass
return self
`