Django多表继承:在子模型之间移动实例

2024-05-02 01:00:19 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我在models.py中有如下内容:

Class ModelA(models.Model):
    # many fields, including
    relatives = models.ManyToManyField(Person)
)

# also, A is foreign key to other models:
Class SomeOtherModel(models.Model):
    mya = models.ForeignKey(A)

# now we produce two classes with multi-table inheritance
# WITHOUT any additional fileds
Class InhertA1(ModelA):
    pass

Class InhertA2(ModelA):
    pass

据我所知,这将为ModelAInheritA1InheritA1创建表;ModelA的每个实例将只在ModelA-表中获得一行,InheritA1的每个实例将在ModelA-表(基本上包含所有数据)和{}-表中创建另一行(只包含一个PK和一个指向的OneToOne键)对ModelA-objects的Django查询将给出所有对象,InheritA1-objects的查询只提供InheritA1-objects等

所以现在我有了一个InheritA1-对象a1,并想把它变成一个InheritA2-对象,而不改变相应的ModelA-对象。所以之前,a1的父IbeToOne键指向键为3的ModelA-行(某些SomeOtherModel-对象的ForeignKey被设置为3)。最后,我希望一个InheritA1-objecta2指向相同的、未更改的ModelA-行(并且对象{}被删除)。在

django似乎没有提供任何这样的move类功能?在

我可以自己安全地实现相应的SQL操作吗?在

或者事情会变得非常糟糕吗?一、 我可以只执行SQL命令吗

  1. InheritA2-表中创建一个新行,将父OneToOne键设置为a1之一
  2. 删除InheritA2-表中的a1行?在

如果不自动创建ModelA-行,我似乎无法从非sqldjango中执行此操作。好吧,对于1,也许我可以这样创建一个临时对象x,然后让p成为{}的父对象,然后将x的父OneToOne键改为指向a1中的一个,然后删除obect p?但是对于2,我认为在非sqldjango中不可能在保留父对象的同时删除子对象的实例?在

或者,有没有一种好的django方法来复制django中的实例并更改对它们的引用?在

也就是说,我可以创建一个新的InheritA2对象y,并将a1的所有属性复制到新对象中,然后遍历数据库,找到指向a1父对象的所有manytomy和ForeignKey项 并将其改为指向y的父对象,然后删除{}。在

这可以用非SQL django实现,缺点是它在性能方面似乎很浪费(这对我的项目来说并不重要),而且它也可能不是那么“稳定”,即,如果我更改ModelA或其他与之相关的模型,那么复制所有内容的代码可能会崩溃?(或者有什么好方法可以做类似的事情

^{pr2}$

前四行似乎很可疑。在

备注:

  • 在不改变实例的情况下进行复制可以用一种稳定、简单、标准的方式完成,例如here,但是我们仍然停留在同一个子类中(并且仍然需要修改foreignkey等)?在
  • {django在声明一个标准选项时,似乎没有人会打破它。在

Tags: 对象django实例内容sqlobjectsmodelsa1
1条回答
网友
1楼 · 发布于 2024-05-02 01:00:19

如果您计划更改子级而不是父级,那么也许可以使用OneToOneField来代替直接继承。在

class ModelA(models.Model):
    pass

class InhertA1(models.Model):
    a = models.OneToOneField(ModelA, primary_key=True)

class InhertA2(models.Model):
    a = models.OneToOneField(ModelA, primary_key=True)

它在数据库中提供相同的3个表。(一个区别是,InheritA1和{}的pk字段将是来自父级的相同id。)

要从InheritA1更改为InheritA2,您将删除一个子实例(这不会影响父实例),然后创建另一个新实例,将其指向父实例。在

好吧,您甚至可以有一个父实例,它有来自其他两个模型的子实例,但是为了防止这种情况发生,您可以在视图中检查它。在

让我知道这是否有帮助,即使回答有点晚。在

相关问题 更多 >