Possible Duplicate:
Polymorphism in Django models




我有一个Constraint抽象基础模型,该模型具有一个Group的外键。几个模型都从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...


但这看起来真的很糟糕。是否存在更好的解决方案?

最佳答案

因此,您是说您拥有Group模型的实例,并且想要与UserConstraint或ProjectConstraint相关的查询集吗?

解决方案可以通过在ForeignKey字段中使用适当的related_name参数来实现此目的。详细信息可在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_name"%(class)s"更改为"%(class)s_set"。以前的值不起作用,我也不知道为什么。

关于python - Django-抽象基类的外键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12483854/

10-11 18:13