Skip to main content
 首页 » 编程设计

python之使用 OneToOneField 的 Django 对象组合

2025年05月04日19daizhj

<分区>

如 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,以便给定的 Widget 将具有 .funwidget 或 .workwidget 。概括地说,我可以提供一种方法 Widget.child(),它检查每个可能的 related_name,但这对我的查询没有帮助。

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

我没能找到具有这种显式一对一映射的简单示例。