【问题标题】:Correctly using subclasses/proxies in django that have self referential foreign keys?在 django 中正确使用具有自引用外键的子类/代理?
【发布时间】:2023-04-06 17:06:01
【问题描述】:

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

以下课程均未完成。我已经尝试过使超类抽象和子类代理。希望下面的代码解释了我想要实现的目标。

这是“超类”

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

这是“叶子”

class User(Owner):
    pass

这是“分支”。

class Group(Owner):
    head = models.ForeignKey(User)
    members = models.ManyToManyField(Owner,through='Membership')

这显示了用户如何通过成员资格属于组。

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

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

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

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

【问题讨论】:

  • 这也是第 27,000,000 个问题,我赢了吗?
  • 我能做的就是点赞。

标签: python django inheritance relational-database django-contenttypes


【解决方案1】:

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

您可能需要为每个 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)

上面的Base 类除了规定每个继承的类在它们各自的数据库表中都有一个name 字段和__unicode__ 方法之外没有其他任何作用。您可以简单地将name 字段和__unicode__ 方法复制并粘贴到UserGroup 中,它在功能上是相同的。拥有一个共同的抽象父级不会创建任何数据库关系,并且您不能使用它来查询数据库。

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

【讨论】:

  • 代理是一个没有成功的想法。最初我想在同一张桌子上。感谢您帮助充实这一点。
猜你喜欢
  • 2016-05-09
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
相关资源
最近更新 更多