Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Django: Comment créer une relation entre 2 classes qui porte des attributs sans créer une troisèmes classes (through) ?

0 votes

J'ai une classe du type:

class Synergy(BaseModel):
    [../..]
    compounds = models.ManyToManyField(EssentialOil, through='SynergyCompound')
    [../..]

Qui pour une relation ManyToMany vers la classe "EssentialOil" mais avec des attributs propre à cette relation. J'ai donc créé une table intermediaire:

class SynergyCompound(BaseModel):
   essential_oil = models.ForeignKey(EssentialOil, on_delete=models.CASCADE, default=None)
   synergy = models.ForeignKey(Synergy, on_delete=models.CASCADE)
   quantity = models.DecimalField(verbose_name=_('quantity'), decimal_places=2, max_digits=4, default=None, null=False,
                               blank=False, validators=[MinValueValidator(Decimal('0.01'))])

En fait il n'y a qu'un seul attribut : quantity !

Je trouve cette approche null car elle conduit à la création d'une table supplémentaire et à des jointure qui seront inutiles.

Quelle approche pourrais-je utiliser pour conserver la valeur "quantity" propre à la relation entre EssentialOil et Synergy sans recourir à cette classe intermédiaire ?

demandé 18-Oct par iopsthecloud (160 points)

1 Réponse

0 votes

En fait, c'est une question de cardinalité dans ton analyse de base de données.
Tu peux jetter un œil à MERISE, ça date un peu mais ça reste assez pertinent...

https://ineumann.developpez.com/tutoriels/merise/initiation-merise/

Pour stocker une relation m2m, avec le modèle relationnel, il faut une table de relation entre les 2 clés primaires, pour dire "[Synergy Foo ] <=> [EssentialOil.Bar]" et "en même temps"
"[Synergy Foo] <=> [EssentialOil.Baz]"

Django crée donc une table, et c'est ce qui est souhaité : c'est la seule façon dans un SGBDR de stocker ce type de relation.

La table créé n'a que les champs essentiloil_id et synergy_id, et le couple est une PK...

Quand tu ajoutes un attribut à la relation, tu passes par le through et tu dois créer la table explicitement.

répondu 19-Oct par frague (662 points)

Sachant que je suis dans une relation 0n--0n je ne peux pas le coupler à un PK justement :(

En refomulant ma question, existe-il un moyen pythonique (ou django) pour gérer ce cas où l’attribut porté par la relation m2m n'a absolument pas besoin d'être dans une SGDBR car c'est un élément secondaire.

...