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