Django - 来自抽象基类的外键

时间:2012-09-18 19:39:27

标签: python django inheritance model

  

可能重复:
  Polymorphism in Django models

我有一个Constraint抽象基础模型,它具有组的外键。从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,我需要能够找到一个指向它的约束模型实例列表。

e.g。如果我做

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...

但这看起来真的很糟糕。有没有更好的解决方案?

1 个答案:

答案 0 :(得分:1)

那么,你的意思是你有Group模型的实例,你想要有相关的查询集给UserConstraint或ProjectConstraint?

通过ForeignKey字段中的适当related_name参数,可以实现此目的。详情请参阅docs

我认为您应该像这样定义Constraint模型:

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"。以前的值不起作用,我不知道为什么。