How to create a record by pasting a relation to the inheriting source Model in the Model inherited by Django
When pasting a relation to the inheritance source Model, the inheritance source Model may be changed to an unintended value. I will write it including cautions and workarounds!
~~ I was confused by the behavior of Django ~~ I love Django
Python==3.7.4 Django=2.2.3
Give a Model object to the {model name} _ptr field that is implicitly defined during Model inheritance
At this time, if you execute Model.save () or Model.objects.create (), the inherited model may be changed to an unintended value, so use .save_base (raw = True). To do
#Model definition
from django.db import models
class Parent(models.Model):
parent_column = models.CharField(max_length=255)
#Model inheriting ParentModel
class Child(Parent):
child_column = models.CharField(max_length=255)
parent = Parent.objects.create(
parent_column="Text"
)
#Create an inheritance destination model with a relation attached to the created inheritance source model
child = Child(
parent_ptr=parent,
child_column="Text"
)
child.save_base(raw=True)
If Model is inherited, the field of the inheriting model is also inherited.
In the database, the Child table does not have a parent_column and a foreign key to the Parent table is created
class Child(Parent):
child_colum = models.CharField(max_length=255)
#Inherited parent_column also exists
# parent_colum = models.CharField(max_length=255)
#Implicitly the inheritance source OneToOneField is also defined
# parent_ptr = models.OneToOneField(
# Parent,
# parent_link=True
# )
As a note
The value of Parent.parent_column will be empty if you do the following:
parent = Parent.objects.create(parent_column="Text")
Child.objects.create(
parent_ptr=parent,
child_column="Text"
)
""Returns
print(Parent.objects.get(pk=parent.pk).parent_column)
this is,
Occurs because parent_link = True is defined in the parent_ptr field of ChildModel
As a result, the parent of parent_ptr = parent is updated at the time of create.
ChildModel also defines an inherited parent_column field
By creating without specifying a value in this field, it will be updated on the parent side. To avoid this
By using Model.save_base (raw = True), you can insert the inherited model without updating the inherited model.
Recommended Posts