【发布时间】:2014-02-21 12:45:48
【问题描述】:
我对 Django 很陌生,我正在尝试在 Django 模型中实现多态性,但我不知道该怎么做。在继续之前,我必须说我已经尝试过 django-model-utils 和 django-polymorphism,但它们并没有完全符合我的要求。
我有一个名为 Player 的模型,每个玩家都有一个角色,每个角色都有不同的行为(即他们的方法返回不同的值):
class Player(models.Model):
username=models.TextField()
role=models.ForeignKey(Role) #Role is another model with a field called ’name'
def allow_action(self)
#some stuff
class RoleA():
def allow_action(self):
#some specific stuff
class RoleB():
pass
我希望每次检索 Player 的任何实例(例如通过 Player.objects.filter(...))时,每个实例的 allow_action() 方法都会被特定类(RoleA、RoleB、 etc...) 或者如果相关子类没有同名调用的方法(RoleA、RoleB 等...是存储在 Player.role.name 中的相同角色名称),则使用 Player 中提供的默认方法。
约束:
由于子类(RolaA、RoleB 等)不添加新字段而只覆盖方法,所有数据都必须存储在 Player 的表中,所以我不想使用 Django 多表继承更类似于代理。
我不想执行额外的 JOIN 来确定特定的子类类型,因为所需的所有信息都存储在 Player 的表中。
我认为这是一种标准的多态模式,但我不知道如何在 Django 中为所有玩家使用同一张表来实现它(我已经实现了这种多态,但没有链接到 Django 模型)。我已经看到 Django 有一种称为“代理”的继承,但它不允许像 Player.objects.filter(...) 那样进行查询并获取方法被自定义方法覆盖的实例(或者至少这是我所理解的)。
提前致谢。
【问题讨论】:
-
为什么django-polymorphic 不适合您的需求?除非我遗漏了什么,否则您可以完全按照自己的意愿行事。
-
@PeteTinkler 根据这个example 它违反了我的第一个约束,即使用多表继承将为每个子类创建一个新表,但我不想要这些表,因为我的数据库将是被未使用的表污染(我将有很多 RoleA、RoleB、RoleC 等)。我认为这同样适用于你下面的 sn-p。
-
那些数据库表不会被使用。您将创建
RoleA...RoleX实例并使用Role基类中的name属性。 -
我不知道 Django 是否会使用这些表,但它们在逻辑上不是必需的。我按照article 解决了这个问题,它没有使用最佳编程实践(它涉及 self.__class__ 赋值),但它用几行代码解决了我的问题。
标签: python django inheritance django-models