Django OneToOneField - 我应该把它放在哪个模型中?

aem*_*mdy 12 django one-to-one

我们假设我们有以下模型.

class A(Model): pass
class B(Model): pass
Run Code Online (Sandbox Code Playgroud)

然后没有区别:

在模型A中: b = OneToOneField(B, related_name=A.__name__)

在模型B中: a = OneToOneField(A, related_name=B.__name__)

那么我应该问自己什么问题来决定是否将OTO放在一个或另一个模型中.我的意思是像has-a,is-a等等.

Eri*_*ing 28

实际上,放置一对一字段的位置存在差异,因为删除行为有所不同.删除对象时,将删除引用该对象的具有一对一关系的任何其他对象.相反,如果您删除包含一对一字段的对象(即它引用其他对象,但其他对象未引用它),则不会删除其他对象.

例如:

class A(models.Model):
    pass

class B(models.Model):
    a = models.OneToOneField(A)
Run Code Online (Sandbox Code Playgroud)

如果删除A,默认情况下B也会被删除(尽管你可以通过修改OneToOneField上的on_delete参数来覆盖它,就像使用ForeignKey一样).删除B不会删除A(尽管您可以通过覆盖B)上的delete()方法来更改此行为.

回到你的初始问题has-a vs. is-a,如果A有B,B应该有一对一的字段(B应该只存在,如果A存在,但A可以存在而不存在B).


Chr*_*att 8

OneToOneFields实际上只有两个目的:1)继承(Django使用它们来实现MTI)或2)扩展不可编辑的模型(比如创建UserProfilefor User).

在这两种情况下,显而易见的是哪种模型OneToOneField.在继承的情况下,它继续在孩子身上.在扩展的情况下,它是您可以访问的唯一模型.

除了少数例外,任何其他一对一的使用都应该真正合并到一个单一的模型中.