2011-12-18 45 views
7

我已經建立了這樣的模式:Django管理變更列表過濾/鏈接到其他車型

class ParentModel(models.Model): 
    some_col = models.IntegerField() 
    some_other = models.CharField() 

class ChildModel(models.Model) 
    parent = models.ForeignKey(ParentModel, related_name='children') 

class ToyModel(models.Model) 
    child_owner = models.ForeignKey(ChildModel, related_name='toys') 

現在,當我打開變更列表爲ParentModel我的管理面板我想在list_display一個新的領域/列用鏈接打開ChildModel的更改列表,但使用應用的篩選器僅顯示所選父項中的子項。現在我用這種方法實現的,但我認爲有一個更清潔的方式做到這一點,我只是不知道如何:

class ParentAdmin(admin.ModelAdmin) 
    list_display = ('id', 'some_col', 'some_other', 'list_children') 
    def list_children(self, obj): 
     url = urlresolvers.reverse('admin:appname_childmodel_changelist') 
     return '<a href="{0}?parent__id__exact={1}">List children</a>'.format(url, obj.id) 
    list_children.allow_tags = True 
    list_children.short_description = 'Children'   

admin.site.register(Parent, ParentAdmin) 

所以我的問題是,是否有可能實現這個不一樣「鏈接黑客」? 還有可能在ParentModel更改列表的單獨列中指明其子女是否有玩具?

回答

2

我認爲你的方法來顯示list_children列是正確的。不要擔心'鏈接黑客',這很好。

要顯示用於指示對象的任何孩子是否有玩具的列,只需在ParentAdmin類中定義另一種方法,然後像以前一樣將其添加到list_display

class ParentAdmin(admin.ModelAdmin): 
    list_display = ('id', 'some_col', 'some_other', 'list_children', 'children_has_toys') 
    ... 
    def children_has_toys(self, obj): 
     """ 
     Returns 'yes' if any of the object's children has toys, otherwise 'no' 
     """ 
     return ToyModel.objects.filter(child_owner__parent=obj).exists() 
    children_has_toys.boolean = True 

設置boolean=True意味着Django會呈現「開」或「關」圖標作爲它的布爾字段。請注意,這種方法每個父代需要一個查詢(即O(n))。您必須測試以確定您是否在生產中獲得了可接受的性能。

+0

謝謝你的回答,這確實對我幫助很大。我很驚訝,django沒有更好的更改鏈接功能。無論如何謝謝,你的幫助現在解決了我所有的問題。 – 2011-12-18 13:44:04