【问题标题】:Change the polymorphic content type of a django model instance更改 django 模型实例的多态内容类型
【发布时间】:2017-01-21 05:23:28
【问题描述】:

如果我有一个多态模型:

class Father(polymorphic.model.PolymorphicModel)

还有一个没有额外字段的继承类:

class Child(Father)

当我有一个父亲的实例时,如何将它转换为一个子实例?

我试过的是:

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 对象,并且需要将其放入子数据库表中。

【问题讨论】:

    标签: django django-contenttypes django-polymorphic


    【解决方案1】:

    好的。

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

    foo.__class__ = Child
    

    这会在子表中进行插入,否则永远不会发生。

    【讨论】:

      【解决方案2】:

      Django 会自动将条目复制到父项中的子项中。对于创建 Child 类的迁移,您只需将新的 Child 对象保存在 DB 中(使用 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)]
      

      【讨论】:

        【解决方案3】:

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

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-21
          • 2012-08-05
          • 1970-01-01
          • 1970-01-01
          • 2019-07-29
          • 1970-01-01
          • 2018-11-21
          相关资源
          最近更新 更多