Django - 来自抽象基类的外键[重复]

Posted

技术标签:

【中文标题】Django - 来自抽象基类的外键[重复]【英文标题】:Django - Foreign key from abstract base class [duplicate] 【发布时间】:2012-09-11 02:54:23 【问题描述】:

可能重复:Polymorphism in Django models

我有一个约束抽象基础模型,它有一个组的外键。几个模型从 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”等。

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

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

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

【问题讨论】:

***.com/questions/5360995/… 【参考方案1】:

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

【讨论】:

我希望能够一次查询所有约束。例如group.() 应该返回用户和项目约束。从那里开始,我将在每个子类中拥有相同的函数名称,因此无论它位于哪个子类中,调用 c.get_constraint_type() 都将起作用。 在后台必须有两个查询到数据库,所以很难用一个查询集来完成。如果您有一堆子类,也许不错的选择是自省约束以使用Constraint.__subclasses__() 方法获取子类并生成要加入的查询集列表。 如果你想要related_name的复数,你需要在末尾添加一个额外的s:“%(class)ss”。

以上是关于Django - 来自抽象基类的外键[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Grails 域模型中的继承导致重复的外键

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

实体框架添加重复的外键

可以保存重复值的外键

配置抽象基类而不在 EF Core 中创建表 [重复]

删除连接表的重复记录并修复相关表上的外键