使用OneToOneField的Django对象组合

时间:2015-05-08 15:30:33

标签: python django orm

other questions所述,Django专家喜欢 Two Scoops 建议显式OneToOneFields而不是多表继承,以避免隐式连接的性能损失。我试图遵循这样的方法,我的设计实际上是对象组合,但有一些问题。所有这三个都是具体的表格。

class Widget:
  ... many shared fields ...

class FunWidget:
  parent = models.OneToOneField(Widget, related_name='child', primary_key=True)
  ... fun-specific fields ...

class WorkWidget:
  parent = models.OneToOneField(Widget, related_name='child', primary_key=True)
  ... work-specific fields ...

我的问题是:

  1. 相关名称:给定Widget,最好引用具有相同名称的相关子类型,例如Widget.child。但是,我收到Reverse query name for ... clashes with reverse query name for ...错误。因此,似乎我必须提供不同的related_name s,以便给定的Widget可以包含.funwidget.workwidget。为了概括,我可以提供一种方法Widget.child()来检查每个可能的related_name,但这对查询无效。

  2. 按子类型过滤:给定QuerySet Widget,我需要过滤到给定“子类型”的所有内容。我意识到你通常只是查询子模型,但这是针对Widget的自定义查询集,我需要根据“子类”的类型执行不同的过滤。换句话说,我想要这样的Widget.objects.filter(isinstance(child, WorkWidget)),我意识到这是不可能的。目前我通过检查Widget的一些不同属性来“打字”(问题1中的我的困境提供了这样的功能)。如果必须的话,Cleaner将存储一个明确的.type字段。

  3. 我没有找到这种明确的一对一映射的简单示例。

1 个答案:

答案 0 :(得分:1)

  1. 你是对的,相关的名字必须不同。
  2. 只需检查是否存在给定的子类型:

    Widget.objects.select_related( 'workwidget')。过滤器(workwidget__isnull =假)