使用Django将外键设置为抽象基类 [英] Setting up a foreign key to an abstract base class with Django

查看:128
本文介绍了使用Django将外键设置为抽象基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我把这两个类的常用属性分解成一个抽象基类,但是我有另一个模型需要引用这些类之一。不可能引用ABC,因为它实际上没有数据库表。



以下示例应该说明我的问题:

 类答案(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 an Answer_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:

    My main concern is neither database structure nor performance (although these changes should improve performance) but code maintainability.

    这篇关于使用Django将外键设置为抽象基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆