在Django中正确使用具有自引用外键的子类/代理?

2024-06-11 19:45:38 发布

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

我有两个班,一个超级班。本质上,这两个类是树上的具体类。一个是叶子,一个是树枝。它们共享超级类中定义的属性。在

以下课程都没有完成。我尝试过使超类抽象化,并使子类代理。希望下面的代码能解释我要实现的目标。在

这是“超级班”

class Owner(models.Model):
    name = models.CharField(max_length=200)
    def __unicode__(self):
        return self.name
    class Meta:
        abstract=True

这是“叶子”

^{pr2}$

这是“树枝”。在

^{3}$

这显示了用户如何通过成员身份属于组。在

class Membership(models.Model):
    date_joined = models.DateField()
    user = models.ForeignKey(Owner)
    group = models.ForeignKey(Group)

我的限制是每个用户可以属于多个组(通过链接器Membership)。每个组可以是单个组的成员。在

这失败了,因为我在成员资格和组成员中都引用了所有者。我觉得这是我可以用Java中的泛型来解决的问题,但这在这里帮不了我。在

我也看到过ContentTypes用于这种排序的东西,但它们对于我要做的事情来说似乎太复杂了。我错了吗?我不知道如何将这个范例应用到我的例子中。我也发现了this问题,但我仍然不确定该如何实现。在


Tags: 用户nameselfmodel属性定义models成员
1条回答
网友
1楼 · 发布于 2024-06-11 19:45:38

不能让外键字段指向抽象类(数据库中没有抽象类的表)。在

您可能需要实现自引用外键,使每个Group属于零或一个组。像这样:

class Base(models.Model):
    name = models.CharField(max_length=200)
    def __unicode__(self):
        return self.name
    class Meta:
        abstract=True


class User(Base):
    groups = models.ManyToManyField('Group', through='Membership', related_name='members')


class Group(Base):
    head = models.ForeignKey(User)
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children')

    def descendants(self, **kwargs):
        qs = self.children_set.filter(**kwargs)
        for group in self.children_set.all():
            qs = qs | group.descendants(**kwargs)
        return qs


class Membership(models.Model):
    date_joined = models.DateField()
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)

上面的cd2{cd2}中继承的每个类都没有比cd2}更多的指令。您可以简单地将name字段和__unicode__方法复制并粘贴到User和{}中,并且功能相同。拥有一个公共的抽象父对象不会创建任何数据库关系,也不能使用它来查询数据库。在

我真的看不出在这种情况下使用代理类的任何理由。在

相关问题 更多 >