( Mise à jour : Pour Django 1.2 et les versions plus récentes, qui peuvent suivre les requêtes select_related à travers les relations inverses OneToOneField (et donc dans les hiérarchies d'héritage), il existe une meilleure technique qui ne nécessite pas l'ajout de l'outil de gestion de l'héritage. real_type
sur le modèle parent. Il est disponible en tant que InheritanceManager en el django-model-utils projet.)
La façon habituelle de procéder est d'ajouter une clé étrangère à ContentType sur le modèle parent qui stocke le type de contenu de la classe "feuille" appropriée. Sans cela, vous pouvez avoir à faire un certain nombre de requêtes sur les tables enfant pour trouver l'instance, selon la taille de votre arbre d'héritage. Voici comment je l'ai fait dans un projet :
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
Elle est implémentée en tant que classe de base abstraite afin de la rendre réutilisable ; vous pourriez également placer ces méthodes et le FK directement sur la classe parent dans votre hiérarchie d'héritage particulière.
Cette solution ne fonctionnera pas si vous n'êtes pas en mesure de modifier le modèle parent. Dans ce cas, vous devrez vérifier manuellement toutes les sous-classes.
80 votes
@S.Lott Ce genre de réponses devient vraiment vieux. Ce n'est pas parce que vous ne pensez pas à un cas d'utilisation que l'auteur de la question n'en a pas. Si vous utilisez la sous-classification pour tout type de comportement polymorphe (vous savez, l'un des principaux avantages supposés de la POO ?), cette question est une nécessité très naturelle et évidente.
82 votes
@S.Lott Dans ce cas, n'hésitez pas à pratiquer des versions non impolies, telles que "Je ne suis pas sûr de comprendre le contexte". Pourriez-vous expliquer votre cas d'utilisation ?"