为什么要将id和pk都设置为None来复制带继承的Django模型?

时间:2012-08-10 14:53:37

标签: django django-models

Django文档推荐copying a model instance因此:

original.pk = None
original.save()

但是如果你“使用继承” - 显然意味着如果模型的类是models.Model的子类的子类 - 你需要稍微改变它。

具体来说,文档说:

  

由于继承的工作原理,您必须将pk和id都设置为None:

并给出了一个类似的例子:

original.pk = None
original.id = None
original.save()

这似乎很笨拙。无论如何,我想了解发生了什么。为什么使用继承要求您将id字段也设置为None?在任何情况下,难道并非所有Django模型都继承自models.Model吗?

(注意:我忽略了关于复制m2m字段的文档中的这一点,顺便说一下,它似乎更加笨拙。)

1 个答案:

答案 0 :(得分:6)

这是因为您在这里讨论的类型MTI(多表继承)将对象存储在多个表中。举个例子:

class Animal(models.Model):
    ...

class Dog(Animal):
    ...

当您创建Dog时,Animal上的所有字段都会保存到Animal的表格中,而Dog上的字段只会保存到表格中为Dog。当您稍后查找Dog时,Django会查询这两个表并将它们拼接在一起。

然而,两个表都需要主键,而Django使用AutoField,这只是正整数字段。因此Dog有一个ID,Animal有一个ID。 pk填充了Animal部分的ID,因为这是主要部分,而Dog的ID无关紧要。但是,如果您要复制,则需要复制这两个部分。否则,副本的Animal部分将不会获得副本的Dog部分。