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.

Figer un modèle Django

+1 vote

Je dispose de plusieurs modèles dans une application métiers. Ces modèles ont des relations entre eux. De facto la modification d'un modèle lié se répercute sur tous les modèles liés.

A à un moment donner je souhaite figer un ou plusieurs modèles.

Typiquement

class ModelA(models.Model):
    field1 = models.CharField(..)
    field2 = models.models.OneToOneField(ModelB)
    field3 = models.ForeignKey(ModelC)

class ModelB(models.Model):
    field1 = models.CharField(..)

class ModelC(models.Model):
     field1 = models.CharField(...)

Dans mes vues la représentation de ModelB et ModelC c'est de la sortie unicode de chaque modèle qui est basée sur field1.

Je souhaiterai donc figer ModelA afin que la modification de ModelB ou ModelC n'ai plus d'impact.

Mon idée de base serait donc de recréer un modèle ModelAFreeze avec uniquement des Fields ne faisant pas appel à des clés étrangères (typiquement CharField...).

Existe-t-il un pattern, une django app ou une best practice pour arriver à cela ?

demandé 26-Fev-2016 par renaudManda (156 points)

Je ne comprends pas la phrase " De facto la modification d'un modèle lié se répercute sur tous les modèles liés."

1 Réponse

0 votes

Je ne connais pas de pattern pour cela, mais je ferai un modelX avec les 3 charfield et dont ModelA hériterait pour en surcharger ce dont on a besoin.

(Désolé de pas te mettre du code , je suis sur une tablette, c'est pas tiptop pour répondre après avoir modere ;) par contre si l'idée du "freeze" c'est de pointer sur la même table sans les contraintes, ça marchera pas. Pour ça j'aurai bien voulu connaître la raison d'un tel choix.

répondu 26-Fev-2016 par foxmask (2,874 points)

Quelque chose comme ça ?

class ModelX(models.Model):
    field1 = models.CHarField(..)
    field2 = models.CHarField(..)
    field3 = models.CHarField(..)

class ModelA(ModelX):
    pass

Mais là je perds la capacité d'avoir un modèle relationnel exploitable avant de figer mon modèle non ?

L'objectif c'est bien de pouvoir pleinement exploiter l'ORM jusqu'au moment où pour des raisons métiers on souhaite figer une vue telle qu'elle est (même si il faut pour cela recréer un modèle "flat").

Le problème c'est que l'on parle base de données et que si "figer" c'est faire sauter les contraintes d'intégrité quand bon me semble pour un besoin ou un autre, ça finira mal , c'est pour ca que je voudrai bien d'avoir quel besoin nécessite de faire "figer" . peux tu développer ?

Le coté immuable est par exemple important lorsque l'on parte de comptabilité.

En ensemble de modèle coopère dans processus metier. A partir d'un moment ce processus arrive dans une phase où les données ne bougent comme pour la comptabilité. Une fois que c'est facturé rien ne bouge. En gros on imprime :)

Briser les contraintes (qui n'en sont pas, je parlerai plutôt de lien) est justement ce que je veux.

Car si mon modelB change typiquement le nom d'un produit qui passe de "FOO" à "BAR", certe le nom peux changer pour tout ce qui n'est pas facturé, mais si sur une facture comptable son nom est "FOO", je ne veux pas que sur son équivalent "numérique"/"S.I." je me retrouve avec "BAR".

Renaud

Si on ne veut pas que les noms des produits changent dans la facture, lors de la facturation on créé les produits dans une autre table qui concervera les noms des produits facturés. Ainsi la table produits pourra changer le nom du produit si ça lui chante.

Donc pour résumer, un petit batch qui pond dans une table produit_factures les produits facturés

Ainsi la table produits pourra vivre sa vie et la table factures aussi

Totalement d'accord avec le dernier commentaire de foxmask. C'est plus "d'un historique de ce qui a ete facturé" dont on a besoin ici, amha. Je me suis que ce lien pourrait etre interessant.

@Nsukami_

Comme je le décrivais plus haut le modèle que je souhaite "figer" à des liens avec d'autres modèles qui peuvent évoluer dans le temps.

si on reprend le code de mon exemple class ModelA(models.model) dispose de plusieurs clés étrangères une vers ModelB et une autre vers ModelC

Je ne l'ai pas précisé dans ma question d'origine mais ModelA à un état. Lorsque cet état arrive à "Facturer" par exemple je souhaiterai aplanir les clés étrangères pour n'avoir que leurs représentation typiquement l'appel à la méthode __str__ de chque modèles liés.

Avec l'ensemble des commentaires je vois qu'il n'y a pas vraiment de pattern ou de solution "out of the box" :)

Donc je m'oriente doucement vers 2 options:

  • l'ultracrade: utilisé une app telle que django-bakery qui me permettrait éventuellement de générer une vue à plat.
  • l'autre :): qui serait de dev une app spécifique (archives) avec le (en fait les) ModelA qui n'utiliserait plus de clés étrangères et où celles-ci seraient replacées directement par leur représentation. Par contre quid du coté "scalable" lorsque modelAchange au cours du temps... sic !

@renaudManda Bien sur que toi seul maitrise tres exactement ce que tu essayes de realiser. Mais quand je te lis, ce que je vois cest que tu as besoin d'un historique, de pouvoir dire "a tel instant ds le passé, j'ai facturé X, Y etait en relation avec X, et Z etait en relation avec X", le tout, meme si les attributs de X changent avec le temps.

Donc "figer" un modele n'est pas ce dont tu as besoin, amha, mais plutot, copier l'etat de ton Modele X, lorsqu'il est est a l'etat facturé, (avec ses relations) vers une autre table qui ne servira qu'a .... enfin, comme l'a deja expliqué foxmask :)

J'espere que tu trouveras une solution facile a mettre en oeuvre.

...