( Update : Für Django 1.2 und höher, das select_related-Abfragen über umgekehrte OneToOneField-Beziehungen (und damit über Vererbungshierarchien hinweg) folgen kann, steht eine bessere Technik zur Verfügung, für die das hinzugefügte real_type
Feld im übergeordneten Modell nicht erforderlich ist . Sie ist als InheritanceManager im verfügbar django-model-utils- Projekt.)
Die übliche Methode hierfür ist das Hinzufügen eines ForeignKey zu ContentType im übergeordneten Modell, in dem der Inhaltstyp der richtigen "Blatt" -Klasse gespeichert wird. Ohne dies müssen Sie möglicherweise eine ganze Reihe von Abfragen für untergeordnete Tabellen durchführen, um die Instanz zu finden, je nachdem, wie groß Ihr Vererbungsbaum ist. So habe ich es in einem Projekt gemacht:
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
Dies wird als abstrakte Basisklasse implementiert, um sie wiederverwendbar zu machen. Sie können diese Methoden und die FK auch direkt in die übergeordnete Klasse in Ihrer speziellen Vererbungshierarchie einfügen.
Diese Lösung funktioniert nicht, wenn Sie das übergeordnete Modell nicht ändern können. In diesem Fall stecken Sie ziemlich fest und überprüfen alle Unterklassen manuell.