我认为这有点棘手,至少对我来说是这样。
所以我有四个模型Person, Singer, Bassist 和 Ninja.
Singer, Bassist 和 Ninja 继承自 Person.
问题在于每个 Person 可以是其子类中的任何一个。
例如,一个人可以是 Singer 和 Ninja。另一个人可以是 Bassist 和 Ninja。另一个人可以是全部三个。
我该如何组织我的模型?
非常感谢您的帮助!
我认为这有点棘手,至少对我来说是这样。
所以我有四个模型Person, Singer, Bassist 和 Ninja.
Singer, Bassist 和 Ninja 继承自 Person.
问题在于每个 Person 可以是其子类中的任何一个。
例如,一个人可以是 Singer 和 Ninja。另一个人可以是 Bassist 和 Ninja。另一个人可以是全部三个。
我该如何组织我的模型?
非常感谢您的帮助!
多重继承在数据库中效果不佳(而你的Django模型最终需要映射到数据库中),而且继承往往是建模“角色”的一种糟糕方式(因为人们的角色会发生变化)。我会将Singer、Bassist和Ninja作为“角色”,而不是Person的子类,并通过外键连接它们:
class Singer(models.Model):
person = models.ForeignKey('Person')
# ...
class Person(models.Model):
# ...
thisperson.singer_set.all()
等方法有什么问题吗? - Alex Martelli原则上,您可以像以下方式一样进行操作:
class Role(models.Model):
......
class Ninja(Role):
.......
class Person(models.Model):
roles = models.ManyToManyField(Role)
但是你会遇到一个问题,即Person.roles.objects.all()只能给你Role类的实例。因此,你需要一种方法将每个Role实例转换为适当的子类,如Ninja或Pirate。这里有一个讨论这个问题的线程链接。
http://groups.google.com/group/django-users/browse_thread/thread/f4241bc16455f92d/7268c3f7bca6b046
所以简而言之,Alex和Stefano给出的答案比我更有用。我同意Alex所描绘的角色解决方案。你拥有的不是人的不同子类,而是一个人可以拥有的不同角色。
但是我听到你说:“嘿,忍者可以有属性“numberOfStars”,而歌手可以有属性“highestNote”。接口也是同样的道理:忍者可以有方法throwStar()和disappear(),歌手可以有sing()和getWasted(),低音吉他手可以有goFunky()和slapPop()。”
在这里,你需要一个非常宽松的数据模型。如此宽松以至于你根本没有模式。如果歌手决定拿起贝斯演奏即兴曲,那没问题。如果他想扮演忍者,你调用throwStar()将会返回一个错误,因为他没有星星,但原则上,你可以给歌手分配星星并让他扔星星。
你正在涉足本体论的世界,而不是模式的世界。你有一个资源,这个资源是“某物”,这个“某物”可以是某种类型,具有某些属性等。一些属性的存在可以推断出类型,或者某些类型的存在可以推断出其他类型。你不能轻易地使用简单的django数据模型来描述这些信息。你需要一个上下文感知的、推理的图形存储,例如AllegroGraph,或使用rdflib实现你的自定义解决方案。