( Update : for Django 1.2 and later, which can follow the select_related query through the OneToOneField backward relationship (and therefore down the inheritance hierarchy), there is a more advanced technical feature that does not require the added real_type field in the parent model. It is available as InheritanceManager into the django-model-utils project.)
The usual way to do this is to add a ForeignKey in the ContentType to the parent model, which stores the content type of the corresponding sheet class. Without this, you may need to perform quite a few queries on child tables to find an instance, depending on how large your inheritance tree is. Here's how I did it in one project:
from django.contrib.contenttypes.models import ContentType from django.db import models class InheritanceCastModel(models.Model): """ An abstract base class that provides a ''real_type'' FK to ContentType. For use in trees of inherited models, to be able to downcast parent instances to their child types. """ real_type = models.ForeignKey(ContentType, editable=False) def save(self, *args, **kwargs): if not self._state.adding: self.real_type = self._get_real_type() super(InheritanceCastModel, self).save(*args, **kwargs) def _get_real_type(self): return ContentType.objects.get_for_model(type(self)) def cast(self): return self.real_type.get_object_for_this_type(pk=self.pk) class Meta: abstract = True
It is implemented as an abstract base class to make it reusable; you can also put these methods and FK directly into the parent class in your specific inheritance hierarchy.
This solution will not work if you cannot change the parent model. In this case, you almost completely check all subclasses manually.
Carl Meyer May 30 '09 at 15:47 2009-05-30 15:47
source share