2012-10-08 49 views
8

我遇到了類似的問題,如 How to query abstract-class-based objects in Django? 該線程建議使用multi_table_inheritance。我個人認爲使用CONTENT_TYPE多個概念舒服(只是感覺更接近的邏輯,至少對我來說)Django:使用ContentType與multi_table_inheritance

使用上鍊接的例子,我想補充一個StelarType作爲

class StellarType(models.Model): 
    """ 
    Use ContentType so we have a single access to all types 
    """ 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

然後添加此抽象示範基地

class StellarObject(BaseModel): 
    title = models.CharField(max_length=255) 
    description = models.TextField() 
    slug = models.SlugField(blank=True, null=True) 
    stellartype = generic.GenericForeignKey(StellarType) 
    class Meta: 
     abstract = True 

要StellarObject和StellarType之間同步,我們可以連接post_save信號每次創建一個行星或恆星時間創建StellarType實例。通過這種方式,我可以通過StellarType查詢StellarObjects。 所以我想知道使用這種方法反對使用multi_table_inheritance的PRO和CON是什麼?我認爲在數據庫中都會創建一個額外的表格。但是數據庫性能呢?可用性/靈活性如何?感謝您的任何意見!

回答

5

對於我來說,當您想要將對象與基本上不具有相同「類型」的多個模型中的某一個關聯時,ContentType就是要走的路。就像如果你想能夠在社交網絡上鍵入評論給用戶,頁面和圖片一樣,但是這三種模型沒有合理的超類型。當然你可以創建一個「可評論」的超類型,但對我來說,這更像是一個混合,而不是這三種東西從中產生的基本類型。在ContentType出來之前,你將別無選擇,只能爲這種關係創造超類型,如果你需要在同一個應用程序中多次執行它,它可以非常快速地變得非常難看(可以說你也有事件,警報,消息等,每個消息都可以應用於不同的一組模型)。

當您想要將屬性附加到基礎模型時,多表繼承是最有意義的,這樣它們將在所有擴展它的具體模型中共享,以便您可以獲得多態行爲。可註釋的並不適合這種模式,因爲所有這些行爲都可以放在評論模型上,而不是在可評論的對象上。但是,如果你有不同類別的用戶共享大部分相同的行爲並且應該是可聚合的,那麼它就更有意義。

對我來說,多表繼承的主要親是一個更乾淨的數據模型,可以在Python方面利用隱式關係和繼承(雖然多態性仍然有點混亂,如看到herehere) 。 ContentType的主要專業是它更通用並且保留了模型中的輔助功能,代價是略微不太原始的模式(模型中用於定義這些關係的大量「元」字段)。而對於你的例子,你仍然必須依靠post_save,這對我來說似乎不必要地混亂/神奇。

+0

我對使用ContentTypes框架使用不相關的東西有同樣的感覺,但使用多表繼承時我感到有點不舒服。試圖在最佳實踐世界中引導,我在pydanny的書(2勺)中讀過多桌是邪惡的。最後一個問題是:效率還是優雅? – lborgav

+2

我*愛*兩勺,但對多表繼承的一攬子告誡我真的不明白。您只需瞭解將爲您的應用程序生成的查詢以及它們是否代表問題。如果你可以在超類型表上完成大部分工作,那麼它特別沒有問題。從性能的角度來看,我無法想到爲什麼查詢超類型表並加入子類應該比爲通用ContentType表做同樣的事情更糟糕。我可以看到爲什麼你想避免一個真正複雜的類型層次,但... – acjay

+1

我同意你的看法。並尋找一個很好的方式來處理這個我剛剛發現這個應用程序(django-model-utils),這似乎是非常有用的:[InheritanceManager](https://django-model-utils.readthedocs.org/en/ latest/managers.html) – lborgav

0

對不起,重振舊線程。我認爲這一切都歸結爲查找方向。無論您是查找某個FK(多繼承)的所有子類,還是將所引用的類定義爲內容類型,並根據表引用和id(contenttypes)查找它們,性能都沒有太大差異 - 提示:它們都吸引人。如果您希望您的應用可以輕鬆擴展,我認爲內容類型是一個不錯的選擇,即其他人可以添加新的內容類型以供參考。如果您只有時需要額外表中定義的額外列,那麼多項式很好。有時候,合併所有的子類型並且只創建一個幾個空字段大部分時間空的也可能是一個好主意。

相關問題