使用Django将外键设置为抽象基类 [英] Setting up a foreign key to an abstract base class with Django
问题描述
以下示例应该说明我的问题:
类答案(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)
consequences = models.IntegerField(choices = CONSEQUENCE_CHOICES)
class Meta:
abstract = True
class Answer_A(答案):
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):
答案= models.ForeignKey(答案)
risk = models.CharField(max_length = 200)
def __unicode __(self):
return self.risk $ b $答案A和答案B略有不同,因为答案A还需要与另一个表格的FK关系。b
Answer_B稍后也可能需要一些特定的属性。如果我有Answer_B是超类 - 并且具有Answer_A子类或撰写它,那么问题仍然存在。
无论是Answer_A还是Answer_B,风险都是一样的。我还有其他型号需要引用答案,而不管它是什么子类型。如何才能做到这一点?如何引用一个类型,而不管它的子类型?
更新:
我试图避免加入操作,但是我不认为我将能够。在所有答案中,值得参考居民,只要在需要的情况下将其置零?还是认为这是非常糟糕的做法?
A 通用关系似乎是解决方案。但是这会使事情更加复杂。
在我看来,您的模型结构已经比必要更复杂了。我将简单地将所有三个答案
模型合并成一个。这样:
-
Answer_Risk
将无需修改即可。 - 如果
Answer_A
,您可以将驻留
设置为None(NULL)。 - 您可以根据
resident == None
返回不同的字符串表示。 (换句话说,相同的功能)
还有一件事;您的答案可能有多种风险?如果他们没有或一个风险,你应该考虑以下替代实现:
- 使用一对一的关系
- c code code code code code code code code code code code code $
我主要关心的不是数据库结构和性能(尽管这些改变应该能提高性能),但是代码可维护性。
I've factored out common attributes from two classes into an abstract base class, however I have another model that needs to reference either one of those classes. It's not possible to reference an ABC as it doesn't actually have a database table.
The following example should illustrate my problem:
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 and Answer_B are slightly different in that Answer_A also needs a FK relationship to another table. Answer_B may also require some specific attributes later. The problem would STILL exist if I had Answer_B be the superclass - and have Answer_A subclass or compose it.
A 'Risk' is the same whether it's Answer_A or Answer_B. I also have other models that need to reference an 'Answer' regardless of it's sub-type. How can this be done? How can you reference a type regardless of it's sub-type?
Update:
I was trying to avoid a join operation but I don't think I'm going to be able to. Would it be worth having the reference to 'Resident' in all 'Answer's and just nulling it where required? Or is that considered very bad practice?解决方案A generic relation seems to be the solution. But it will complicate things even further.
It seems to me; your model structure is already more complex than necessary. I would simply merge all three
Answer
models into one. This way:Answer_Risk
would work without modification.- You can set
resident
to None (NULL) in case of anAnswer_A
. - You can return different string represantations depending on
resident == None
. (in other words; same functionality)
One more thing; are your answers likely to have more than one risk? If they'll have none or one risk you should consider following alternative implementations:
- Using a one-to-one relationship
- Demoting risk as a field (or any number of fields) inside
Answer
class.
My main concern is neither database structure nor performance (although these changes should improve performance) but code maintainability.
这篇关于使用Django将外键设置为抽象基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!