2012-10-25 124 views
2

對於我的某個模型,我有以下概念設計。Django模型 - 共享公共基類的不同對象類型的外鍵

class A(models.Model): 
    ... 

class B(A): #Inherits A 
    fieldA = ... 
    fieldB = ... 

class C(A): #Inherits A 
    fieldC = ... 
    fieldD = ... 

class D(models.Model): 
    field = models.ForeignKey(A) #Here lies the problem, should store B or C 

鑑於以上的車型,我想一個外鍵存儲到d B或C,但不能同時

我試圖設置A的Meta類屬性來抽象,但不允許ForeignKey關係爲A.我不要想要有一個不是B或C的A實例,但如果必要的,我可以用保存信號來限制這種行爲。

是否有一個更容易的設計,可以讓我從一個類型列表中存儲一個外鍵,其中所有類都從一個公共基類繼承而來?

+0

你能想到在那裏你可以做一個抽象的情況,有一箇中介T接着B,C和d均來自T.繼承或者,也許從一個具體的延長A. B,C和d見本同樣的問題,這是有點舊http://stackoverflow.com/questions/1114767/django-model-inheritance-and-foreign-keys –

回答

1

我能想到的兩個選項:

  1. D類使用generic relation,而不是一個外鍵。

  2. 如果您不需要使用從BC特定的字段,你可以繼續你現在有辦法來過濾D,但添加到D的方法,將檢索子類的field

    class D(models.Model): 
        field = models.ForeignKey(A) 
    
        def get_field(self): 
         try: 
          return self.field.b 
         except B.DoesNotExist: 
          pass 
         try: 
          return self.field.c 
         except C.DoesNotExist: 
          pass 
    

    這絕對會影響性能,正如您在文章中所說的,您必須手動確保每個A實例都有BC子類。顯然這種方法不能很好地擴展,如果你打算有n個子類。

+0

我很高興我不是唯一的,目前我已經實施你所描述的在2中,我對代碼非常不舒服。 – Valchris

+0

是的,它不漂亮,但它的工作原理。 – dgel

+0

使其更具可伸縮性的另一個選擇是將字段添加到您的'A'類(可能是ContentType的外鍵),該字段將保存子類型的元數據。那麼你不必全部嘗試。 – dgel