【问题标题】:Model Inheritance or Foreign Key?模型继承还是外键?
【发布时间】:2018-09-10 08:55:09
【问题描述】:

我确信可能有几种方法可以实现我正在实现的目标,但遇到了一些问题。我有一个“成员”模型,并且我还尝试添加一个“从属”模型,该模型从父(成员)继承一些字段和数据,但也有一些相同的字段,但它们自己的数据。实现这一目标的最佳方法是什么? ForeignKey、OneToOne 或 ManyToMany,甚至有可能吗?

例子:

class Member(models.Model):
    name = models.CharField(max_length=128)
    address = models.CharField(max_length=128)
    age = models.DateField()

class Dependent(models.Model):
    name = models.CharField(max_length=128) (different name)
    address = models.CharField(max_length=128) (same address as Member)
    age = models.DateField() (different age)

感谢您的帮助。

【问题讨论】:

  • 这里的is_dependent 标志不应该是最佳选择吗?所以 BooleanField 表示它是否是依赖项。此外,1-1、m2m 和ForeignKey 具有不同的量词,因此这不是“设计”问题,而是根本的建模差异。
  • ForeignKey 似乎是最好的主意,因为继承在这里没有多大意义,而且这可能不是一对一关系或多对多关系。
  • 另一方面,如果Member 可以有零个、一个或多个Dependents,则ForeignKey 将模拟多对一关系。您还可以使用包含共享字段的 abstract 模型。
  • 但以上内容不清楚,所以我认为您应该提供更多信息:DependentMember 有什么关系?一个成员可以有零个、一个或多个Dependents? Dependent 可以有零个、一个或多个 Members 吗? DependentMember吗?
  • 你真的应该让MemberDependant 之间的语义关系更清晰,正如@WillemVanOnsem 所要求的那样。否则无法正确回答此问题。

标签: python django model


【解决方案1】:

由于DependentMember 具有相同的字段,但有一些额外的字段,您可以使DependentMember 都继承abstract base class(感谢@WillemVanOnsem 指出)以避免重新定义相同的字段,并且由于MemberDependent 具有父子关系,因此您应该将外键添加到Member 作为Dependent 模型中的附加字段。您还可以覆盖Membersave 方法,使其在保存时同步其Dependent 子级的地址。

class Person(models.Model):
    name = models.CharField(max_length=128)
    address = models.CharField(max_length=128)
    age = models.DateField()

    class Meta:
        abstract = True

class Member(Person):
    def save(self):
        super().save()
        self.dependents.exclude(address=self.address).update(address=self.address)

class Dependent(Person):
    parent = models.ForeignKey(Member, related_name='dependents')
    extra_field = ...

【讨论】:

  • 但是通过继承一个非抽象模型,你已经有了一个“隐式”parent 关系,只不过它更像是一个OneToOneField。见:godjango.com/blog/…
  • 这里的隐含父母并不是真正的父母,而只是继承人的基本身份。仍然需要外键来表示真正的父子关系。
  • @bihsing:但是你在哪里读到了多对一的问题。这里的父子关系可以指两件事:(a)继承,或(b)DependentMember 具有多对一的事实。此外,通过使用这种继承,我们将需要额外的JOINs 来获取数据。尽管 Django 中涵盖了继承,但这通常不是好的做法。
  • 确实如此。我只是通过“依赖”一词的含义来推断多对一的关系(并且它应该与父级共享相同的地址)。从它在现实世界中可能使用的角度来看,这对我来说是有意义的。
  • 关于非抽象模型继承的固有缺陷的好点。我已经更新了我的答案,改为使用抽象基类。感谢您指出。
猜你喜欢
  • 2010-11-10
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2012-06-09
  • 2021-06-05
  • 2019-11-17
相关资源
最近更新 更多