我有一个Django应用程序,它有许多不同的模型,都带有一堆常见数据。最终,我认为这个问题归结为继承与构成之间的决定。我目前的实现是这样的:
class Thing(models.Model):
foo = models.FooField()
bar = models.BarField()
type = models.CharField()
class A(CommonStuff):
aFoo = models.FooField()
class B(CommonStuff):
bFoo = models.FooField()
使用此模型,我可以使用Thing模型的管理器查询Thing
。使用Thing
上的类型字段,我可以通过查看type
字段来获取子对象数据,该字段包含'a'或'b',然后请求(即){{1 }}。这是我喜欢的一个功能,因为在我的应用中,获取所有thing.a.aFoo
个对象的列表是一个相当常见的操作。
我在这里看到几个问题。首先,Thing
字段似乎没必要。有没有办法获得子数据而无需先查找类型?似乎我可以通过一个实例方法解决这个问题,该方法返回给定其类型值的正确对象,或者如果我真的想要摆脱类型字段,我可以迭代{{1}上的每个反向关系字段},寻找一个不会引发type
异常的问题。这对我来说感觉很脆弱。如果我添加新的“subthing”Thing
,我必须更新DoesNotExist
以查找新类型。我可以通过制作C
和抽象模型来解决这个问题。这样,Thing
和Thing
获取A
的所有字段,并且我避免使用B
字段。但问题是我失去了对所有Thing
个对象执行查询的能力。
我正在思考的另一个模型是将type
中的数据转换为Thing
和Thing
上的字段,从而将这个模型翻转过来。
A
这个版本有一些好处。它摆脱了B
上的class Thing(models.Model):
foo = models.FooField()
bar = models.BarField()
class A(models.Model):
aFoo = models.FooField()
thing = models.OneToOneField(Thing)
class B(models.Model):
bFoo = models.FooField()
thing = models.OneToOneField(Thing)
字段,至少对我来说,看起来更清洁,更不易碎。但是,这里的问题与在第一个版本中使type
抽象的问题相同。我失去了一起查询所有'子主题'的能力。我可以查询Thing
个对象或查询Thing
个对象,但不能同时查询两者。可以使用这个版本的模型而不必牺牲查询所有“子主题”的能力吗?一种可能性是编写一个查询两个模型并返回所有对象A
的管理器。这有用吗?