7
votes

Trouvez un objet dans la classe enfant de l'objet en classe des parents à Django

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?


2 commentaires

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


6 Réponses :


-2
votes

de The Docs : < / p>

Si vous avez un place qui est également un restaurant , vous pouvez obtenir à partir de l'objet place au restaurant "/ Code> objet en utilisant la version minuscule du nom du modèle ...


7 commentaires

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 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.



7
votes

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 -Method qui retournera l'objet enfant!


2 commentaires

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 .



0
votes

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 () dans votre des chosesThamigrate Classe de modèle: < Pré> xxx


1 commentaires

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 __ peut ne pas contenir la liste complète des sous-classes. Introspection Les relations sont plus sûres.



2
votes

héritage concret ou abstrait? Si béton: xxx

Ceci peut être automatisé à l'aide de Django-modèle -utils inheritanCemanager (alors vous n'avez pas besoin de vous inquiéter de Select_Related ou de la liste manuelle de toutes les sous-classes possibles). Maintenu par un autre développeur de base Django.


3 commentaires

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 , 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.



0
votes

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


2 commentaires

Souffle également des sous-classes potentiellement incomplètes __ __ 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



0
votes

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.
Laissez un exemple de code le prouver: xxx

il prend une ligne, objets = inheritanCanager () dans votre modèle parent.


0 commentaires