Héritage de modèles Django Le sujet est résolu

Tout ce qui concerne la programmation.
Répondre
Avatar de l’utilisateur
Dunatotatos
Membre
Membre
Messages : 425
Inscription : 11 mai 2016, 20:56
Status : Hors-ligne

Re,

Je rencontre un souci en Django. Comme je sais que quelques-uns ici touche le sujet, je poste ma question.

J'ai deux applications différentes, l'une de gestion de recette, une autre de gestion de stock. Les deux applications utilise chacun une classe Ingredient.
Dans recette/models.py :

Code : Tout sélectionner

class Ingredient(models.Model):
    nom = models.CharField(max_length = 20)
Imaginons que des méthodes un peu complexe soient implémentées ici (récupérer les détails du produit selon une référence externe stockée dans un attribut, lister des allergènes, vérifier le respect de diverses normes, ...)

Dans l'application stock, j'ai la même classe Ingredient. Pour éviter de devoir me retaper le codage de toutes les méthodes complexes, je fais juste un héritage dans stock/models.py :

Code : Tout sélectionner

from recette.models import Ingredient as ext_Ingredient

class Ingredient(ext_Ingredient):
    quantite = models.IntegerField()
Maintenant, si je crée un objet stock.models.Ingredient, il apparaît quand je liste les recette.models.Ingredient. C'est un peu gênant. Un ingrédient en stock n'est pas forcément impliqué dans une recette. Comment gérer ça ?
J'ai envisager plusieurs réponses :
  • l'architecture n'est pas logique, l'héritage entre application n'est pas vraiment "best practice" ;
  • créer une classe abstraite avec les méthodes complexes, puis rendre les deux classes Ingredients soeur (fille de la classe abstraite) ;
  • ajouter un attribut dans recette.models.Ingredient pour indiquer si l'objet est impliqué dans l'application, ou s'il vient d'ailleurs (c'est moche !) ;
  • trouver un paramétrage de Django qui permet de stocker les deux classes dans des tables différentes.
Merci pour votre aide !
Duna
Avatar de l’utilisateur
vohu
Membre
Membre
Messages : 455
Inscription : 16 avr. 2016, 12:02
Localisation : Strasbourg
Status : Hors-ligne

Ce que tu cherches s'appelle apparement l'héritage muti-table -> https://docs.djangoproject.com/fr/1.9/t ... nheritance

Par contre, je ne comprends pas trop ton problème :

Il est normal que tous les ingrédients s'affiche si tu affiche la liste des ingrédients (même ceux qui ne sont pas utilisés). Si tu veux afficher les ingrédients d'une recette, tu dois requetter sur une instance de LA recette en question et il n'y a aucune raison qu'un ingrédient non lié s'affiche.
Avatar de l’utilisateur
Dunatotatos
Membre
Membre
Messages : 425
Inscription : 11 mai 2016, 20:56
Status : Hors-ligne

L'héritage multi-table est exactement ce que je fais dans mon exemple. Et ça ne me convient pas, parce-que (en suivant l'exemple de la doc), les Restaurants sont listés dans les Places.

Tu as raison sur ton commentaire. Dans le cas de l'exemple que j'ai donné, pour lister la totalité des Ingrédients utilisés dans une recette, il est préférable de lister les Ingrédients de chaque Recette. Mais c'est un exemple simplifié. En plus, je trouve malsain d'avoir des données générées par par une autre application dans une table de l'application Recette.
Dans le cas concret qui m'intéresse, il n'y a pas de classe Recette. Les Ingrédients existent seuls, sans lien avec une autre classe. (Il s'agit de publications, en fait, et les méthodes complexes me permettent de récupérer la liste des auteurs, le journal de parution, ou le titre à partir de l'ID de pubmed. Pour afficher la liste des publications, je n'ai d'autre choix que d'utiliser publications.models.Publication.objects.all())
Avatar de l’utilisateur
Dunatotatos
Membre
Membre
Messages : 425
Inscription : 11 mai 2016, 20:56
Status : Hors-ligne

Pour info, j'ai résolu mon souci en créant une classe Publication avec mes méthodes complexes, puis en créant une classe Publication_DB qui hérite de Publication et de models.Model.
Dans ma seconde application, je peux donc recréer une classe qui hérite de Publication et de models.Model, qui sera donc indépendante de Publicaiton_DB.

Ce n'est pas très propre, mais je n'ai pas trouvé mieux.
Répondre