1

可能的重复:
Django 模型中的多态性

我有一个约束抽象基础模型,它有一个组的外键。几个模型从 Constraint 继承,以各种不同的方式运行。这是我所拥有的(非常简化的)版本:

class Constraint(models.Model):
    group = models.ForeignKey(Group)

    def get_constraint_type(self):
        return 'Base'

    class meta:
        abstract = True

class UserConstraint(Constraint):
    user = models.ForeignKey(User)

    def get_constraint_type(self):
        return 'User'

class ProjectConstraint(Constraint):
    project = models.ForeignKey(Project)

    def get_constraint_type(self):
        return 'Project'

给定一个组,我需要能够提出一个指向它的约束模型实例列表。

例如,如果我这样做

group = ...
constraints = group.constraint_set.all()
for c in constraints:
    print c.get_constrait_type()

现在,它会打印 'Base' 很多次,而不是 'User'、'Project'、'User' 等。

一个非常 hacky 的解决方案是在基类中实现这样的函数:

def get_child(self):
    try:
        return self.usercontraint
    except UserConstraint.DoesNotExist:
        pass
    try:
        return self.projectcontraint
    except ProjectConstraint.DoesNotExist:
        pass
    # etc...

但这似乎真的很糟糕。有没有更好的解决方案?

4

1 回答 1

2

所以,你的意思是你有 Group 模型的实例,并且你想拥有与 UserConstraint 或 ProjectConstraint 相关的查询集?

有解决方案可以related_name在 ForeignKey 字段中使用适当的参数来实现这一点。详细信息可在docs中找到。

我认为你应该像这样定义约束模型:

class Constraint(models.Model):
    group = models.ForeignKey(Group, related_name="%(class)s_set")

    def get_constraint_type(self):
        return 'Base'

    class Meta:
        abstract = True

并像这样使用它:

user_constraints = group.userconstraint_set.all()
project_constraints = group.projectconstraint_set.all()

编辑:

我已将related_namefrom更改"%(class)s""%(class)s_set". 以前的值不起作用,我不知道为什么。

于 2012-09-18T19:50:01.357 回答