我有这样的模型设置:
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
变更列表的单独列中指出,如果它的任何孩子都有玩具?
我认为您显示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会像处理布尔字段一样渲染'on'或'off'图标。注意,这种方法需要每个父节点一个查询(即O(n))。您必须进行测试,看看在生产环境中是否可以获得可接受的性能。