当前位置:  开发笔记 > 编程语言 > 正文

使用Django为抽象基类设置外键

如何解决《使用Django为抽象基类设置外键》经验,为你挑选了2个好方法。

我已经将两个类的公共属性分解为一个抽象基类,但是我有另一个模型需要引用其中一个类.不可能引用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,'风险'都是相同的.我还有其他模型需要引用'答案'而不管它的子类型.如何才能做到这一点?无论它的子类型如何,您如何引用类型?

更新:
我试图避免加入操作但我不认为我能够.是否值得在所有'答案'中引用'Resident'并在必要时将其归零?或者这被认为是非常糟糕的做法?



1> muhuk..:

一个通用的关系似乎是解决方案.但它会使事情进一步复杂化.

在我看来; 您的模型结构已经比必要的更复杂.我只想将所有三个Answer模型合并为一个.这条路:

Answer_Risk 无需修改即可使用.

如果是,则可以设置resident为None(NULL)Answer_A.

您可以根据需要返回不同的字符串represantations resident == None.(换句话说;相同的功能)

还有一件事; 您的答案可能有多种风险吗?如果他们没有或有一个风险,您应该考虑采用以下替代实施:

使用一对一的关系

将风险降级为类内的字段(或任意数量的字段)Answer.

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



2> Daniel Naab..:

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

或者,你可以保留你的模型为是,但有更换ForeignKey的动物来GenericForeignKey.你在模型继承的语法糖中失去了什么,你获得了一点查询速度.

我不相信可以通过ForeignKey(或任何功能相同的)引用抽象基础模型.

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有