( Actualización : para Django 1.2 y versiones posteriores, que pueden seguir consultas select_related en relaciones OneToOneField inversas (y, por lo tanto, jerarquías de herencia descendentes), hay una técnica mejor disponible que no requiere el real_type
campo agregado en el modelo principal. Está disponible como InheritanceManager en el proyecto django-model-utils .)
La forma habitual de hacer esto es agregar una ForeignKey a ContentType en el modelo principal que almacena el tipo de contenido de la clase "hoja" adecuada. Sin esto, es posible que tenga que hacer una gran cantidad de consultas en tablas secundarias para encontrar la instancia, dependiendo de qué tan grande sea su árbol de herencia. Así es como lo hice en un proyecto:
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 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
Esto se implementa como una clase base abstracta para que sea reutilizable; también puede poner estos métodos y el FK directamente en la clase padre en su jerarquía de herencia particular.
Esta solución no funcionará si no puede modificar el modelo principal. En ese caso, está prácticamente atascado comprobando todas las subclases manualmente.