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