棘手的模型继承 - Django

时间:2010-03-22 02:01:42

标签: python django inheritance django-models django-orm

我觉得这有点棘手,至少对我而言。 :)

所以我有4个模特歌手 Bassist Ninja

歌手,贝斯手和忍者继承人。


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

e.g。一个人可以是歌手和忍者。另一个人可以是贝斯手和忍者。另外一个可以全部三个。

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


非常感谢帮助!

4 个答案:

答案 0 :(得分:15)

多重继承不适用于数据库(并且您的Django模型最终需要映射到数据库),并且继承通常是模拟“角色”的一种不好的方式(因为人们的角色确实发生了变化)。我会让Singer,Bassist和Ninja成为“角色”,作为Person的子类,并通过外键连接它们:

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

class Person(models.Model):
    # ...

答案 1 :(得分: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给出的答案比我更有用。

答案 2 :(得分:2)

我同意角色解决方案,正如亚历克斯所描述的那样。你拥有的不是人的不同子类。你可以拥有不同的角色。

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

这里有一个数据模型需要非常松散的模式的情况。事实上,你根本没有架构。如果歌手决定拿低音和即兴曲调,那很好。如果他想扮演一个忍者,并且你打电话给throwStar,它会返回一个错误,因为他没有星星,但你原则上可以将星星分配给歌手并让他投掷星星。

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

答案 3 :(得分:1)

您可以让所有职业(Ninja,Bassist ......)继承模型中的 Person ,然后在后端代码中使用 isinstance 功能区分的职业。