我已经将两个类的公共属性分解为一个抽象基类,但是我有另一个模型需要引用其中一个类.不可能引用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'并在必要时将其归零?或者这被认为是非常糟糕的做法?
一个通用的关系似乎是解决方案.但它会使事情进一步复杂化.
在我看来; 您的模型结构已经比必要的更复杂.我只想将所有三个Answer
模型合并为一个.这条路:
Answer_Risk
无需修改即可使用.
如果是,则可以设置resident
为None(NULL)Answer_A
.
您可以根据需要返回不同的字符串represantations resident == None
.(换句话说;相同的功能)
还有一件事; 您的答案可能有多种风险吗?如果他们没有或有一个风险,您应该考虑采用以下替代实施:
使用一对一的关系
将风险降级为类内的字段(或任意数量的字段)Answer
.
我主要关注的不是数据库结构和性能(尽管这些更改应该提高性能),而是代码可维护性.
我的直觉是建议删除基类上的抽象修饰符.你将得到相同的模型结构,但答案将是它自己的表.这样做的缺点是,如果这些是大型表和/或您的查询很复杂,对它的查询可能会明显变慢.
或者,你可以保留你的模型为是,但有更换ForeignKey的动物来GenericForeignKey.你在模型继承的语法糖中失去了什么,你获得了一点查询速度.
我不相信可以通过ForeignKey(或任何功能相同的)引用抽象基础模型.