Disons que j'ai une classe de parents (des choses à partir de deux enfants (noix de coco et hirondelle). Disons maintenant que j'ai un objet des objets. Comment puis-je déterminer s'il est en fait une noix de coco ou une hirondelle? Une fois l'avoir fait, comment puis-je vous rendre à la noix de coco ou à l'objet d'hirondelle? P>
6 Réponses :
de The Docs : < / p>
Si vous avez un
place code> qui est également un restaurant code>, vous pouvez obtenir à partir de l'objet code> place code> au restaurant
"/ Code> objet en utilisant la version minuscule du nom du modèle ... p> blockQuote>
Mais si, comme je la pose dans ma question, j'ai un objet de la place et je ne suis pas sûr que c'est un restaurant ou un château?
La réponse à celle-ci est au même endroit, après l'extrait de code.
J'ai lu que Doc plusieurs fois bien sûr. Je ne vois pas la référence dont vous parlez. Parlez-vous du fait évident qui essayant un enfant différent de celui que l'objet est une instance de va-t-elle élever cette classe 'Notexist?
Si vous accédez à somemodel.coconut code> et il jette une exception, il n'est clairement pas une noix de coco et il doit être autre chose.
Oui, je comprends ça. La documentation précise clairement cela. C'est pourquoi j'ai posé la question que j'ai posée, ce qui est - comment puis-je dire ce que c'est? Je n'ai pas demandé comment je peux dire ce que ce n'est pas. Dites-vous que vous croyez avoir besoin de tester chaque classe enfant?
Oui. Bienvenue dans le modèle Héritage à Django.
Je ne ressens pas vraiment l'approche agressive / rudée passive. Je suis déjà très familier avec le héritage modèle à Django. D'une manière ou d'une autre, je n'avais jamais rencontré ce problème. C'est un problème. Si vous êtes correct, il s'agit simplement d'une fonctionnalité importante manquante.
Django n'offre pas un tel polymorphisme de modèle hors de la boîte. Le moyen le plus simple de faire ce que vous essayez d'atteindre est de stocker le type de contenu d'un nouvel objet. Il y a une application générique simple appelée Django-polymorphic-modèles qui vous offre cette fonctionnalité - et - en plus un Down Downcast Code> -Method qui retournera l'objet enfant! P>
J'ai utilisé une technique similaire pour les sous-classes utilisateur et cela fonctionne bien. J'aurais aimé connaître cette application existait auparavant.
J'avais l'habitude d'utiliser cette technique jusqu'à ce que j'ai découvert une meilleure approche. Django-Model-Utils 'inheritanCanager ne nécessite pas le champ de type de contenu supplémentaire, et peut obtenir un résultat hétérogène défini dans une seule requête grâce à l'utilisation interne select_related code>.
Ce n'est pas particulièrement joli ou efficace, mais la meilleure façon de penser à la mettre en œuvre sans stocker les méta-données de la sous-classe dans la DB (comme modèles django-polymorphes fait) serait une méthode enfant () code> dans votre
des chosesThamigrate code> Classe de modèle: < Pré> xxx pré> p>
Bien que dépend de l'endroit où vos sous-classes sont déclarées et comment les instructions d'importation sont structurées, __ sous-classes __ code> peut ne pas contenir la liste complète des sous-classes. Introspection Les relations sont plus sûres.
héritage concret ou abstrait? Si béton: Ceci peut être automatisé à l'aide de Django-modèle -utils inheritanCemanager code> (alors vous n'avez pas besoin de vous inquiéter de
Select_Related code> ou de la liste manuelle de toutes les sous-classes possibles). Maintenu par un autre développeur de base Django. P> p>
Mais cela nécessite que je sache que je cherche une noix de coco ou une hirondelle - je recherche une solution dans laquelle je n'ai pas besoin de connaître le nom de la classe enfant.
C'est pourquoi je vous ai pointé sur InheritanCemanager Code>, et a souligné la manière dont il évite la liste des sous-classes :)
Je pourrais poster un extrait de code montrant comment introduire les relations inverse de l'onetoone pour obtenir ces informations, mais vous êtes probablement mieux à l'aide de HeritanCemanager ou d'inspecter son code source.
sur un Django CMS I Travailler avec (Merengue http://www.merengueproject.org/ ), Nous stockons l'attribut "Nom de classe" qui stocke quelle est la classe réelle de l'objet.
Pour obtenir l'instance réelle, nous avons utilisé la méthode suivante: p>
def get_real_instance(self): """ get object child instance """ def get_subclasses(cls): subclasses = cls.__subclasses__() result = [] for subclass in subclasses: if not subclass._meta.abstract: result.append(subclass) else: result += get_subclasses(subclass) return result if hasattr(self, '_real_instance'): # try looking in our cache return self._real_instance subclasses = get_subclasses(self.__class__) if not subclasses: # already real_instance self._real_instance = getattr(self, self.class_name, self) return self._real_instance else: subclasses_names = [cls.__name__.lower() for cls in subclasses] for subcls_name in subclasses_names: if hasattr(self, subcls_name): return getattr(self, subcls_name, self).get_real_instance() return self
Souffle également des sous-classes potentiellement incomplètes __ __ CODE> Problème, la nécessité d'un champ supplémentaire et des requêtes plus coûteuses que des utils de modèles Django.
Peut-être que Django-Model-Utils ne fonctionne pas correctement avec plusieurs niveaux de héritage. Et je ne reçois vraiment pas ce que le problème présente sous-classes b>
Alors que Drmeer a suggéré, je recommande vivement django-modèle-utils (hébergé sur Bitbucket maintenant). Je ne suis pas sûr que ce soit assez convaincant. il prend une ligne,
Laissez un exemple de code le prouver: objets = inheritanCanager () code> dans votre modèle parent. P> p>
Quelle est la différence entre noix de coco et avaler en interne? C'est-à-dire des champs supplémentaires ou des méthodes que l'on a et l'autre n'est-elle pas?
Champs et méthodes supplémentaires et différentes branches de renforcement de l'héritage