为什么必须将id和pk都设置为None才能复制带有继承的Django模型?

为什么必须将id和pk都设置为None才能复制带有继承的Django模型?,django,django-models,Django,Django Models,因此,Django文件建议: 但是如果你“使用继承”——显然意味着如果模型的类是models.model的子类的子类——你需要稍微不同地去做 具体来说,该文件说: 由于继承的工作方式,您必须将pk和id都设置为None: 并给出了一个类似的例子: original.pk = None original.id = None original.save() 这似乎很难理解。无论如何,我想知道发生了什么。为什么使用继承还需要将id字段设置为None?难道所有Django模型在任何情况下都不是继承自模

因此,Django文件建议:

但是如果你“使用继承”——显然意味着如果模型的类是
models.model
的子类的子类——你需要稍微不同地去做

具体来说,该文件说:

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

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

original.pk = None
original.id = None
original.save()
这似乎很难理解。无论如何,我想知道发生了什么。为什么使用继承还需要将
id
字段设置为
None
?难道所有Django模型在任何情况下都不是继承自
模型.Model

(注意:我省略了文档中关于复制m2m字段的部分,这似乎更麻烦。)

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

class Animal(models.Model):
    ...

class Dog(Animal):
    ...
创建
Dog
时,
Animal
上的所有字段都会保存到
Animal
的表中,而只有
Dog
上的直接字段会保存到
Dog
的表中。当您稍后查找
Dog
时,Django将查询这两个表并将它们缝合在一起


然而,这两个表都需要主键,Django使用
AutoField
s来表示主键,它们只是正整数字段。因此,
Dog
有一个id,
Animal
有一个id。
pk
中填充了
Animal
部分的id,因为这是主要部分,
Dog
的id并不重要。然而,如果你要复制,你需要复制这两个部分。否则,
Animal
部分副本将无法获得它自己的
Dog
部分副本。

收到了,谢谢。后续问题:抽象基类不需要这样做,对吗?也就是说,如果
Animal
是抽象的,那么正常的复制方法just
dog.pk=None
就可以了,是吗?可选的后续问题#2:Django模型没有一个
copy
方法为您解决所有这些问题,这只是我的问题,还是有点奇怪?这已经讨论了5年了……我认为人们对什么是重要的和什么不是重要的看法可能会有很大的分歧。在过去两年每天编写和重构Django代码的过程中,我从未需要制作对象的副本。这并不是说没有很多人会这么做,但就我个人而言,Django是否添加了复制功能与我无关。你必须假设其他人,甚至核心开发团队中的其他人也和我一样冷漠。主观性较低:-),对于使用抽象基类(其本身继承自
models.model
)的模型,可以将
pk
设置为
None
?是的,这只是MTI的问题,任何其他类型的继承或标准模型都不会有问题,因为只涉及一个表。
class Animal(models.Model):
    ...

class Dog(Animal):
    ...