更改 Django 模型实例的多态内容类型
Change the polymorphic content type of a django model instance
如果我有一个多态模型:
class Father(polymorphic.model.PolymorphicModel)
和继承人 class 没有额外字段:
class Child(Father)
当我有 Father 实例时,如何将其转换为 Child 实例?
我试过的是:
foo = Father.objects.get(pk=1)
# foo is just a Father, no record in Child database table.
foo.polymorphic_ctype = ContentType.objects.get(app_label='myapp', model='child')
foo.save()
但没有任何变化。我希望 foo 成为一个子对象并且需要将其放入子数据库 table.
好的。
读完这篇类似的 post 我意识到我需要另一个作业:
foo.__class__ = Child
这会在子项中插入 table 否则永远不会发生。
Django 会自动将条目复制到父项中的子项中。对于创建 Child class 的迁移,您可以简单地将新的 Child 对象保存在数据库中(使用 __dict__ 属性 填充它们 python对象):
在迁移文件中定义此函数:
def duplicate_Children(apps,schema_editor):
Father = apps.get_model('myapp','Father')
Child= apps.get_model('myapp','Child')
for dad in Father.objects.all():
son = Child()
for attr in dad.__dict__:
son.__dict__[attr]=dad.__dict__[attr]
son.save()
...
将此添加到迁移中的操作列表 class:
operations = [migrations.RunPython(duplicate_Children)]
对于多态模型你可以这样做:
kclass = YourChangeClass
# With that do the correct insert
self.__class__ = kclass
# With that change the correct model
ct = ContentType.objects.get_for_model(kclass)
self.polymorphic_ctype = ct
# With that set the default values
self.set_default_values()
self.save()
你需要为每个 class 定义一个定义默认值的方法,因为在其他情况下 save() 会失败!
例如,如果需要从A传递到B:
class A():
attr_1
class B()
attr_2
def set_default_values(self):
self.attr_2 = None
如果我有一个多态模型:
class Father(polymorphic.model.PolymorphicModel)
和继承人 class 没有额外字段:
class Child(Father)
当我有 Father 实例时,如何将其转换为 Child 实例?
我试过的是:
foo = Father.objects.get(pk=1)
# foo is just a Father, no record in Child database table.
foo.polymorphic_ctype = ContentType.objects.get(app_label='myapp', model='child')
foo.save()
但没有任何变化。我希望 foo 成为一个子对象并且需要将其放入子数据库 table.
好的。
读完这篇类似的 post 我意识到我需要另一个作业:
foo.__class__ = Child
这会在子项中插入 table 否则永远不会发生。
Django 会自动将条目复制到父项中的子项中。对于创建 Child class 的迁移,您可以简单地将新的 Child 对象保存在数据库中(使用 __dict__ 属性 填充它们 python对象):
在迁移文件中定义此函数:
def duplicate_Children(apps,schema_editor):
Father = apps.get_model('myapp','Father')
Child= apps.get_model('myapp','Child')
for dad in Father.objects.all():
son = Child()
for attr in dad.__dict__:
son.__dict__[attr]=dad.__dict__[attr]
son.save()
...
将此添加到迁移中的操作列表 class:
operations = [migrations.RunPython(duplicate_Children)]
对于多态模型你可以这样做:
kclass = YourChangeClass
# With that do the correct insert
self.__class__ = kclass
# With that change the correct model
ct = ContentType.objects.get_for_model(kclass)
self.polymorphic_ctype = ct
# With that set the default values
self.set_default_values()
self.save()
你需要为每个 class 定义一个定义默认值的方法,因为在其他情况下 save() 会失败!
例如,如果需要从A传递到B:
class A():
attr_1
class B()
attr_2
def set_default_values(self):
self.attr_2 = None