无多重继承和附加连接的Django模型多态性

2024-09-24 22:22:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Django相当陌生,我正试图在Django模型中实现多态性,但我不知道如何实现。在继续之前,我不得不说我已经尝试过django模型实用程序和django多态性,但它们并不能完全满足我的要求。

我有一个名为Player的模型,每个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,或者使用Player中提供的默认方法,如果相关子类没有同名的方法(RoleA、RoleB等)。。。是否存储了相同的角色名称Player.role.name).

限制条件:

  1. 由于子类(RolaA、RoleB等)不添加新字段,只覆盖方法,所有数据都必须存储在Player的表中,所以我不想使用Django多表继承,而是使用更类似于代理的东西。

  2. 我不想执行额外的联接来确定特定的子类类型,因为所需的所有信息都存储在Player的表中。

我认为这是一个标准的多态模式,但我不知道如何在Django中使用相同的表来实现它(我已经实现了这种多态性,但没有链接到Django模型)。我见过Django有一种称为“Proxy”的继承,但是它不允许像Player.objects.filter(…)并获取方法被自定义覆盖的实例(或者至少这是我所理解的)。

提前谢谢。


Tags: django实例方法模型角色modelsaction子类
1条回答
网友
1楼 · 发布于 2024-09-24 22:22:24

免责声明:我没有使用django-polymorphic,此代码基于扫描文档所花的5分钟,完全未经测试,但我有兴趣看看它是否有效:

from polymorphic import PolymorphicModel


class Role(PolymorphicModel):
    name = models.CharField()


class RoleA(Role):
    def allow_action(self):
        # Some specific stuff...


class RoleB(Role):
    pass


class Player(models.Model):
    username=models.TextField()
    role=models.ForeignKey(Role)    #Role is another model with a field called ’name'

    def allow_action(self)
        if callable(getattr(self.role, "allow_action", None):
            self.role.allow_action()
        else:
            # default action...

现在我相信您应该能够创建Role、RoleA或RoleB的实例,并在外键中使Player指向它。在Player实例上调用allow_action()将检查Role(或RoleARoleB等)的实例是否具有可调用属性allow_action(),如果是,它将使用该属性,否则将使用默认值。在

相关问题 更多 >