Django ModelAdmin中的"list_display"可以显示ForeignKey字段的属性吗?

420 投票
15 回答
252749 浏览
提问于 2025-04-11 09:31

我有一个叫做 Person 的模型,它和 Book 之间有个外键关系。Book 有很多字段,但我最关心的是 author(这是一个普通的字符字段)。

所以在我的 PersonAdmin 模型中,我想用 list_display 来显示 book.author

class PersonAdmin(admin.ModelAdmin):
    list_display = ['book.author',]

我尝试了所有明显的方法,但似乎都不管用。

有没有什么建议?

15 个回答

74

和其他人一样,我也选择了可调用对象(callables)。不过它们有一个缺点:默认情况下,你不能对它们进行排序。幸运的是,有办法解决这个问题:

Django 版本 >= 1.8

def author(self, obj):
    return obj.book.author
author.admin_order_field  = 'book__author'

Django 版本 < 1.8

def author(self):
    return self.book.author
author.admin_order_field  = 'book__author'
203

尽管上面有很多很棒的回答,但因为我刚接触Django,所以还是有点困惑。以下是我从一个新手的角度来解释的内容。

models.py

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=255)

admin.py(错误的方法) - 你可能会认为用'model__field'来引用会有效,但其实并不行。

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'author__name', ]

admin.site.register(Book, BookAdmin)

admin.py(正确的方法) - 这就是用Django的方式来引用外键名称的方法。

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_name', ]

    def get_name(self, obj):
        return obj.author.name
    get_name.admin_order_field  = 'author'  #Allows column order sorting
    get_name.short_description = 'Author Name'  #Renames column head

    #Filtering on side - for some reason, this works
    #list_filter = ['title', 'author__name']

admin.site.register(Book, BookAdmin)

想要更多参考,可以查看Django模型的链接 这里

661

另外一种选择是,你可以这样进行查找:

#models.py
class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')
    
    def get_author(self, obj):
        return obj.book.author
    get_author.short_description = 'Author'
    get_author.admin_order_field = 'book__author'

从Django 3.2开始,你可以使用display()这个装饰器:

#models.py
class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')
    
    @admin.display(ordering='book__author', description='Author')
    def get_author(self, obj):
        return obj.book.author

撰写回答