14

我认为这有点棘手,至少对我来说。:)

所以我有 4 个模型PersonSingerBassistNinja

歌手、贝斯手和忍者继承自 Person。


问题是每个 Person 都可以是它的任何子类。

例如,一个人可以是歌手和忍者。另一个人可以是贝斯手和忍者。另一个可以是所有三个。

我应该如何组织我的模型?


帮助将不胜感激!

4

4 回答 4

15

多重继承不适用于数据库(并且您的 Django 模型最终确实需要映射到数据库),并且继承通常是对“角色”建模的不好方法(因为人们的角色确实会改变)。我会将 Singer、Bassist 和 Ninja 作为“角色”,而不是作为 Person 的子类,并通过外键连接它们:

class Singer(models.Model):
    person = models.ForeignKey('Person')
    # ...

class Person(models.Model):
    # ...
于 2010-03-22T02:09:11.923 回答
3

原则上,您可以执行以下操作:

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 给出了比我更有用的答案。

于 2010-03-22T12:53:39.253 回答
2

我同意 Alex 所描述的角色解决方案。你所拥有的不是不同的人的子类。你有一个人可以扮演的不同角色。

但是我听到你说:“嘿,忍者可以有一个属性“numberOfStars”,而歌手可以有一个属性“highestNote”。与界面相同:忍者可以有方法throwStar()和消失(),而歌手可以有 sing() 和 getWasted(),而贝斯手可以有 goFunky() 和 slapPop()

您在这里遇到的情况是您的数据模型需要一个非常松散的模式。如此松散,事实上,您根本没有架构。如果歌手决定使用贝斯并即兴创作曲子,那很好。如果他想扮演忍者,你调用 throwStar 会返回错误,因为他没有星星,但原则上你可以给歌手分配星星,让他扔星星。

你正在冒险的是本体的世界,而不是模式。你有一个资源,它是“某物”,它可以是某种类型,具有某些属性等。某些属性的存在可以推断出类型,或者某些类型的存在可以推断出其他类型。您无法使用简单的 django 数据模型轻松描述此信息。您需要的是一个上下文感知的推理图形存储,例如 AllegroGraph,或者使用 rdflib 实现您的破解解决方案。

于 2010-03-22T03:20:34.953 回答
1

你可以让你所有的职业(忍者,贝斯手......)继承自模型中的Person,然后在后端代码中使用函数isinstance来区分Person的职业。

于 2013-05-14T22:44:49.567 回答