更改django模型实例的多态内容类型

时间:2016-09-13 14:47:26

标签: django django-contenttypes django-polymorphic

如果我有多态模型:

class Father(polymorphic.model.PolymorphicModel)

和没有额外字段的继承者类:

class Child(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 是一个Child对象,需要将它放入子数据库表中。

3 个答案:

答案 0 :(得分:0)

确定。

在阅读了类似的post后,我意识到我还需要另一项任务:

1
2 6
3 7 11 
4 8 12 16
5 9 13 17 21

这样就可以在子表中插入,否则永远不会发生。

答案 1 :(得分:0)

Django将自动将条目复制到父级的子级中。对于创建Child类的迁移,您只需将新的Child对象保存在数据库中(使用python对象的 __ dict __ 属性填充它们):

在您的迁移文件中定义此功能:

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()

...

将其添加到Migrate类的操作列表中:

operations = [migrations.RunPython(duplicate_Children)]

答案 2 :(得分:0)

对于多态模型,您可以这样做:

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()

您需要为每个类定义一个定义默认值的方法,因为以其他方式,当save()失败时!。

例如,如果您需要从A传递到B:

class A():
    attr_1
class B()
    attr_2
    def set_default_values(self):
        self.attr_2 = None