控制 Django 继承模型中的对象创建流程

Control object creation flow in Django inheritance models

我已经阅读了一些关于继承模型和 parent_link 的 Django 文档。 假设我有这些模型:

class Parent(models.Model):
    #Some field goes here! 
class Child(Parent):
    #Some field goes here! 

关于这个模式我有 3 个问题:

  1. 如果我想创建新的子对象并将现有父对象的id传递给它,我该怎么办?

  2. 如果我只想创建新的子对象,过一段时间再为该子对象创建父对象,我该怎么办?

  3. 另外,我不理解这篇关于 parent_link 的文档:

    OneToOneField.parent_link

    When True and used in a model which inherits from another concrete model, indicates that this field should be used as the link back to the parent class, rather than the extra OneToOneField which would normally be implicitly created by subclassing.

感谢您的帮助!

更新问题 假设这些模型:

class User(AbsteractBaseUser):
    #Some field goes here! 

class Student(User):
    #Some field goes here! 

class Teacher(User):
    #Some field goes here! 

class Employee(User):
    #Some field goes here! 
  1. 是否可以创建 Teacher 对象并为该老师放置现有 User 对象的 pk?

你不能在 Django ORM 中这样做。因为如果你想到数据库,这是可能的,但在 OOP 中,这是不可能的。所以你不应该在 Django ORM 中使用模型继承。当您使用继承时,parent 的外键会在数据库的 child object 中创建,但您无法控制它。您无法在创建时更改或设置它。如果您从数据库的角度来看,当您创建 child object 时,会在数据库中创建两个 object,即一个在 parent 中,一个在 child 中.您应该可以将另一个 parent 分配给此 child object。但是当你看到OOP的观点时,根据OOP原则,当创建一个child时,它继承了parent的所有属性,而只创建了一个object。所以没有自由分配另一个parent object给这个child。

您可以改用抽象模型。如果您不能删除继承,那么您可以使用 RAW SQL 来完成。否则没有任何其他选择。

如果您可以删除继承,请在 child 中使用 parent 创建一个 OnetoOneField。

Django 模型有两种继承类型:抽象继承和具体继承。

在第一种情况下,抽象基础 class 和 "parent record" 都没有 table,每个子模型都有自己的完整 table 和所有字段(继承并拥有)。

在第二种情况下(也称为 "multi-table inheritence",对于具有父模型字段的父模型有一个 table,对于具有 OneToOne 的每个子模型有一个 table字段(技术上是 FK)在父 table 和子模型自己的字段上。创建子记录时,您可以 NOT "control creation"没有父记录的子记录(需要 fk)。

可以(至少在技术上)创建一个没有子记录的父记录,然后创建子记录并link它给父记录(这实际上是 Django当你创建一个子记录时在引擎盖下做,因为子记录需要父级的 fk)但恕我直言,这是一种强烈的设计气味 - 如果你的应用程序有一个没有子级的父级记录是有意义的,那么你可能不应该这样做完全使用继承(您可以在没有继承的情况下使用 OneToOne 字段)。

wrt/ OneToOneField.parent_link :当你使用具体继承并且没有明确地向父模型提供 OneToOne 字段时,Django 会为你创建它(就像它创建一个主键字段一样,如果你不要明确定义一个)。如果您想在子模型中明确定义父模型的 OneToOne 字段,您必须告诉 Django 这个 OneToOne 字段是父模型的 link,这就是这个标志的用途。

最后一点:根据经验,多 table 继承(无论您的数据访问层是什么 - django orm、slqalchemy、普通手册 SQL 等)总是有点像 PITA , 所以只在真正有意义的地方使用它。