2

我已经阅读了一些关于继承模型和parent_link. 假设我有这些模型:

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

    当 True 并用于从另一个具体模型继承的模型中时,表示该字段应用作返回父类的链接,而不是通常由子类化隐式创建的额外 OneToOneField。

谢谢你的帮助!

更新问题 假设这些模型:

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 放置给该老师?
4

2 回答 2

3

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

在第一种情况下,没有抽象基类的表,也没有“父记录”,每个子模型都有自己的完整表,其中包含所有字段(继承和拥有)。

在第二种情况下(也称为“多表继承”),父模型有一个表,其中包含父模型的字段,每个子模型有一个表,在父表上具有 OneToOne 字段(技术上是 FK)和子模型自己的字段。创建子记录时 不能“控制创建”父记录,也不能在没有父记录的情况下创建子记录(需要 fk)。

可以(至少在技术上)创建一个没有子记录的父记录,然后创建子记录并将其链接到父记录(这实际上是 Django 在创建子记录时正在做的事情,因为子记录需要 fk 到父),但恕我直言,这是一种强烈的设计气味-如果您的应用程序在没有子项的情况下拥有父记录是有意义的,那么您可能根本不应该使用继承(您可以使用没有继承的 OneToOne 字段)。

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

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

于 2020-04-15T08:21:59.547 回答
3

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

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

如果您可以删除继承,请在具有父项的子项中创建一个 OnetoOneField。

于 2020-04-15T07:55:58.210 回答