【问题标题】:Setting up a foreign key to an abstract base class with Django使用 Django 为抽象基类设置外键
【发布时间】:2010-09-26 22:00:59
【问题描述】:

我已将两个类中的公共属性分解为一个抽象基类,但是我有另一个模型需要引用这些类中的任何一个。不能引用 ABC,因为它实际上没有数据库表。

下面的例子应该能说明我的问题:

class Answer(models.Model):
    ovramt = models.ForeignKey("Ovramt")
    question = models.ForeignKey("Question")
    answer = models.CharField(max_length=3, choices=(("yes","yes"),("no","no") ("NA","N/A"))
    likelihood = models.IntegerField(choices=LIKELY_CHOICES)
    consequence = models.IntegerField(choices=CONSEQUENCE_CHOICES)

    class Meta:
        abstract = True

class Answer_A(Answer):
    resident = models.ForeignKey("Resident")
    def __unicode__(self):
        return u"%s - %s - %s" %(self.ovramt.ssa.name, self.resident, self.question)    

class Answer_B(Answer):
    def __unicode__(self):
        return u"%s - %s" %(self.ovramt.ssa.name, self.question)    

class Answer_Risk(models.Model):
    answer = models.ForeignKey("Answer")
    risk = models.CharField(max_length=200)

    def __unicode__(self):
        return self.risk

Answer_A 和 Answer_B 略有不同,因为 Answer_A 还需要与另一个表建立 FK 关系。 Answer_B 以后可能还需要一些特定的属性。如果我让 Answer_B 成为超类 - 并且拥有 Answer_A 子类或组合它,问题仍然存在。

无论是 Answer_A 还是 Answer_B,“风险”都是相同的。我还有其他模型需要引用“答案”,无论其子类型如何。如何才能做到这一点?不管它是什么子类型,如何引用一个类型?

更新:
我试图避免加入操作,但我认为我做不到。是否值得在所有“答案”中引用“居民”并在需要时将其取消?或者这被认为是非常糟糕的做法?

【问题讨论】:

    标签: python django inheritance django-models


    【解决方案1】:

    generic relation 似乎是解决方案。但这会让事情变得更加复杂。

    在我看来;您的模型结构已经比必要的复杂。我会简单地将所有三个Answer 模型合并为一个。这样:

    • Answer_Risk 无需修改即可工作。
    • 如果是Answer_A,您可以将resident 设置为None (NULL)。
    • 您可以根据resident == None 返回不同的字符串表示形式。 (换句话说;相同的功能)

    还有一件事;你的答案可能有不止一种风险吗?如果他们没有或只有一种风险,您应该考虑以下替代实现:

    我主要关心的既不是数据库结构也不是性能(尽管这些更改应该会提高性能),而是代码可维护性

    【讨论】:

    • 感谢您的建议,但答案将有 1..M 风险以及 1..M 解决方案 - 所以需要表格。我将在需要时将 resident 设置为 None - 因为这似乎是模型之间的唯一区别。如果以后需要更改,我会这样做。
    • 通用关系链接失效,最新开发版请看这里:docs.djangoproject.com/en/dev/ref/contrib/contenttypes/…
    【解决方案2】:

    我的直觉是建议删除基类上的抽象修饰符。您将获得相同的模型结构,但答案将是它自己的表。这样做的缺点是,如果这些表很大并且/或者您的查询很复杂,那么针对它的查询可能会明显变慢。

    或者,您可以保持模型不变,但将 ForeignKey to Answer 替换为 GenericForeignKey。你在模型继承的语法糖中失去了什么,你在查询速度上获得了一点。

    我认为不可能通过 ForeignKey(或任何功能相同的东西)引用抽象基础模型。

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 1970-01-01
      • 2018-07-09
      • 2016-04-15
      • 2016-06-10
      • 1970-01-01
      • 2011-02-20
      • 2011-11-23
      • 2016-04-19
      相关资源
      最近更新 更多