Comment créer un enregistrement en collant une relation au modèle source d'héritage dans le modèle hérité par Django
Lors du collage d'une relation avec le modèle source d'héritage, le modèle source d'héritage peut être remplacé par une valeur non voulue. Je vais l'écrire avec des mises en garde et des solutions de contournement!
~~ J'étais confus par le comportement de Django ~~ J'aime Django
Python==3.7.4 Django=2.2.3
Donnez un objet Model au champ {model name} _ptr
qui est implicitement défini lors de l'héritage du modèle
À ce stade, si vous exécutez Model.save ()
ou Model.objects.create ()
, le modèle hérité peut être changé en une valeur involontaire, utilisez donc .save_base (raw = True)
. Faire
#Définition du modèle
from django.db import models
class Parent(models.Model):
parent_column = models.CharField(max_length=255)
#Modèle héritant du ParentModel
class Child(Parent):
child_column = models.CharField(max_length=255)
parent = Parent.objects.create(
parent_column="Text"
)
#Créer un modèle de destination d'héritage avec une relation attachée au modèle source d'héritage créé
child = Child(
parent_ptr=parent,
child_column="Text"
)
child.save_base(raw=True)
Si vous héritez de Model, les champs du modèle héritant sont également hérités.
Dans la base de données, la table enfant n'a pas de colonne_parent et une clé externe à la table parent est créée
class Child(Parent):
child_colum = models.CharField(max_length=255)
#Parent hérité_la colonne existe également
# parent_colum = models.CharField(max_length=255)
#Implicitement, la source d'héritage OneToOneField est également définie
# parent_ptr = models.OneToOneField(
# Parent,
# parent_link=True
# )
Comme note
La valeur de Parent.parent_column sera vide si vous procédez comme suit:
parent = Parent.objects.create(parent_column="Text")
Child.objects.create(
parent_ptr=parent,
child_column="Text"
)
""Retour
print(Parent.objects.get(pk=parent.pk).parent_column)
c'est,
Se produit parce que parent_link = True
est défini dans le champ parent_ptr
de ChildModel
En conséquence, le parent de parent_ptr = parent
est mis à jour au moment de la création.
ChildModel définit également un champ parent_column hérité
En créant sans spécifier de valeur dans ce champ, il sera mis à jour côté parent. Pour éviter cela
En utilisant Model.save_base (raw = True)
, vous pouvez insérer le modèle hérité sans mettre à jour le modèle hérité.