Assuming a simple set of inherited Model classes, like this:
class BaseObject(models.Model):
some_field = models.SomeField(...)
class AwesomeObject(BaseObject):
awesome_field = models.AwesomeField(...)
class ExcellentObject(BaseObject):
excellent_field = models.ExcellentField(...)
and a query that looks like this:
found_objects = BaseObject.objects.filter(some_field='bogus')
What’s the best way to take each found object and turn it back into it’s derived class? The code I’m using now is like this:
for found in found_objects:
if hasattr(found, 'awesomeobject'):
ProcessAwesome(found.awesomeobject)
elif hasattr(found, 'excellentobject'):
ProcessExcellent(found.excellentobject):
But, it feels like this is an abuse of “hasattr”. Is there a better way to do this without creating an explicit “type” field on the base class?
That’s the best way that I know of. Unfortunately, inheritance is a little clunky in this regard. Multiple table inheritance is basically just a one-to-one relationship between the parent model and the extra fields the child adds, which is why that
hasattrtrick works. You can think of each of those as aOneToOneFieldattribute on your parent model. When you think of it that way, Django has no way of knowing which child to return or even if to return a child, so you have to handle that logic yourself:I tend to create a method on the parent such as
get_child, which simply cycles through the attributes and returns the one that pops:At least then, you can just call
found.get_child(), and maybe forget about the hackery that gets you there.