2011-04-26 68 views
2

問題在Django管理多態行爲

假設我有三個類A,B和C,B是A的子類,C是B的子類:

A <- B <- C 

當我打開管理員並列出所有「A」,我看到所有的「A」,「B」和「C」。但是,當我按照其中一個鏈接查看細節並編輯特定的B時,即使該實例實際上是C的一個實例,我也只會看到B的字段。我想看到的是根據其最具體的類型向我展示。

我使用InheritanceManager我試圖

獲得在更抽象的層次上工作時,澆鑄成正確的類型實例。這工作得很好(它不能處理多個繼承級別)。但是,即使對於單一繼承級別,我也無法將多態行爲反映到管理員中,因爲顯然管理員不知道經理的方法select_subclasses()

任何想法,我怎麼可以用來獲得這樣的多態行爲的管理?

具體例

models.py:

from django.db import models 
from model_utils.managers import InheritanceManager 

class A(models.Model): 
    a_field = models.CharField(max_length=200) 
    objects = InheritanceManager() 

class B(A): 
    b_field = models.CharField(max_length=200) 

class C(B): 
    c_field = models.CharField(max_length=200) 

admin.py

from myapp.models import A, B, C 
from django.contrib import admin 

admin.site.register(A) 
admin.site.register(B) 
admin.site.register(C) 

更新

增加從2010年到兩個線程的鏈接就如何與實現這一目標的一些想法Django的多態:

回答

2

這個答案是局部的,因爲我不能重現你的第一個問題。列出父模型對象時,我會看到所有這些對象。 (或者可能存在一些誤解)


不完整字段的問題可以通過管理內聯部分解決。由於子類只是一個帶有隱式OneToOneField到父模型的模型,因此可以爲「C」定義內聯,然後將其包含在B的管理員的inlines屬性中。

的問題是:

  • 用戶將不能夠經由B的管理員內聯以創建的「C」類對象;它只能通過C的管理員完成。它只是查看。
  • 它不適用於多繼承級別:您可以將B作爲內聯包含到A的管理員中,但我知道沒有簡單的方法將C作爲內聯嵌入到B的內聯中。

另一種方法是修改A的管理模板,在那裏放置一個指向真實實例(不管是B還是C)的鏈接。但我想你已經想到了。


關於最後一個問題:如果你想修改一些模型管理的查詢集,它可以通過的ModelAdmin的queryset()方法來完成(見this question的例子)。您可以在模型的管理員上覆蓋此方法,並在此處放置邏輯select_subclasses()。但是我沒有嘗試過,所以如果你這樣做,我不能說ModelAdmin的行爲是什麼。也許你需要重寫一些更多的方法。


PS。我目前使用django-polymorphic,開展類似項目的具體繼承。它沒有提供任何方式通過管理來管理多態模型,所以我決定不要過多地依賴Django的管理員,併爲網站員工創建一個簡單的自定義界面,我想這不會花費太多時間。

+0

我爲這個問題增加了一個具體的例子。你是對的,列出所有的「A」也會列出「B」和「C」。我也相應地解決了這個問題,併爲剩下的問題添加了更多細節。 – 2011-05-05 15:05:24

+0

感謝您的內聯建議。我肯定可以解決一些使用它們的問題,但正如你所說,它們的適用性非常有限,而且你提出的問題不容忽視。 'queryset()'方法工作得很好,但它也只適用於單個級別(儘管如此,這更多是對'InheritanceManager'的限制)。 – 2011-05-05 15:19:01

+0

當然,忘記django-admin並從零開始做所有事情也是一種選擇。我看到「免費」管理員是django的一大優點,但它開始看起來對這個項目有限制,因爲它會廣泛使用繼承關係。 – 2011-05-05 15:24:16