I am assuming that all ArticleBase instances are instances of ArticleBase subclasses.
One solution is to store the subclass name in ArticleBase and some methods that return the subclass or subclass object based on that information. As multi-table inheritance defines a property on the parent instance to access a child instance, this is all pretty straight forward.
from django.db import models
class ArticleBase(models.Model):
title = models.CharField()
author = models.CharField()
# Store the actual class name.
class_name = models.CharField()
# Define save to make sure class_name is set.
def save(self, *args, **kwargs):
self.class_name = self.__class__.__name__
super(ArticleBase, self).save(*args, **kwargs)
# Multi-table inheritance defines an attribute to fetch the child
# from a parent instance given the lower case subclass name.
def get_child(self):
return getattr(self, self.class_name.lower())
# If indeed you really need the class.
def get_child_class(self):
return self.get_child().__class__
# Check the type against a subclass name or a subclass.
# For instance, 'if article.child_is(News):'
# or 'if article.child_is("News"):'.
def child_is(self, cls):
if isinstance(cls, basestring):
return cls.lower() == self.class_name.lower()
else:
return self.get_child_class() == cls
class Review(ArticleBase):
rating = models.IntegerField()
class News(ArticleBase):
source = models.CharField()
This is by no means the only way to go about this. It is, however, a pretty simple and straight forward solution. The excellent contrib contenttypes app and the generic module which leverages it offer a wealth of ways to do this, well, generically.
It could be useful to have the following in ArticleBase:
def __unicode__(self)
return self.get_child().__unicode__()
In that case, be aware that failure to define __unicode__
in the subclasses, or calling __unicode__
on an instance of ArticleBase (one that has not been subclassed) would lead to an infinite recursion. Thus the admonition below re sanity checking (for instance, preventing just such an instantiation of ArticleBase directly).
Disclaimer:
This code is untested, I'm sure I've got a typo or two in there, but the basic concept should be sound. Production level code should probably have some sanity checking to intercept usage errors.