我有一个Person模型,它与Book有外键关系,Book有许多字段,但我最关心的是author(一个标准CharField)。
话虽如此,在我的PersonAdmin模型中,我想显示book。作者使用list_display:
class PersonAdmin(admin.ModelAdmin):
list_display = ['book.author',]
我已经尝试了所有显而易见的方法,但似乎都不起作用。
有什么建议吗?
我有一个Person模型,它与Book有外键关系,Book有许多字段,但我最关心的是author(一个标准CharField)。
话虽如此,在我的PersonAdmin模型中,我想显示book。作者使用list_display:
class PersonAdmin(admin.ModelAdmin):
list_display = ['book.author',]
我已经尝试了所有显而易见的方法,但似乎都不起作用。
有什么建议吗?
当前回答
在PyPI中有一个非常容易使用的包可以处理这个问题:django-related-admin。你也可以在GitHub中看到代码。
使用它,你想要达到的效果很简单:
class PersonAdmin(RelatedFieldAdmin):
list_display = ['book__author',]
这两个链接都包含了安装和使用的全部细节,所以我不会把它们粘贴在这里,以防它们发生变化。
顺便说一句,如果你已经在使用模型以外的东西。Admin(例如,我使用的是SimpleHistoryAdmin代替),你可以这样做:类MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin)。
其他回答
对于Django >= 3.2
在Django 3.2或更高版本中,正确的方法是使用显示装饰器
class BookAdmin(admin.ModelAdmin):
model = Book
list_display = ['title', 'get_author_name']
@admin.display(description='Author Name', ordering='author__name')
def get_author_name(self, obj):
return obj.author.name
根据文档,你只能显示ForeignKey的__unicode__表示:
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display
似乎奇怪的是,它不支持'book__author'风格的格式,这种格式在DB API中随处可见。
事实证明,这个功能有一个门票,它被标记为不会修复。
AlexRobbins的回答对我来说很有用,除了前两行需要在模型中(也许这是假设的?),并且应该引用self:
def book_author(self):
return self.book.author
然后管理部分工作得很好。
请注意,添加get_author函数会减慢管理中的list_display,因为显示每个人会产生SQL查询。
为了避免这种情况,您需要修改PersonAdmin中的get_queryset方法,例如:
def get_queryset(self, request):
return super(PersonAdmin,self).get_queryset(request).select_related('book')
之前:36.02ms内73个查询(管理中67个重复查询) 之后:10.81ms内查询6次
在PyPI中有一个非常容易使用的包可以处理这个问题:django-related-admin。你也可以在GitHub中看到代码。
使用它,你想要达到的效果很简单:
class PersonAdmin(RelatedFieldAdmin):
list_display = ['book__author',]
这两个链接都包含了安装和使用的全部细节,所以我不会把它们粘贴在这里,以防它们发生变化。
顺便说一句,如果你已经在使用模型以外的东西。Admin(例如,我使用的是SimpleHistoryAdmin代替),你可以这样做:类MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin)。