如何在Django admin `list_display`中显示外键和多对多字段?

How to display the foreign key and many-to-many fields in Django admin `list_display`?

如何在Django admin中显示外键和多对多字段list_display

models.py:

class Book(models.Model):
    title = models.CharField(max_length=150, blank=False)

class Character(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='character')
    name = models.CharField(max_length=50)

class Author(models.Model):
    book = models.ManyToManyField(Book, related_name='author')
    name = models.CharField(max_length=50)

admin.py:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'characters', 'authors')

    def characters(self, obj):
        ???

    def authors(self, obj):
        ???

您可以获取相关的 characters/authors,然后将名称加入以逗号分隔的列表中:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'characters', 'authors')

    def characters(self, obj):
        return <b>', '</b>.join([c.name for c in obj.character.all()])

    def authors(self, obj):
        return <b>', '</b>.join([a.name for a in obj.author.all()])

我们可以通过使用 .prefetch_related(…) [Django-doc] 批量获取所有相关对象来提高性能:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'characters', 'authors')

    def characters(self, obj):
        return ', '.join([c.name for c in obj.character.all()])

    def authors(self, obj):
        return ', '.join([a.name for a in obj.author.all()])

    def get_queryset(self, request):
        return super().get_queryset(request)<b>.prefetch_related(</b>
            'character', 'author'
        <b>)</b>

因为related_name是倒序关系,可以有多个Characters/Authors,所以有道理给它们起一个 复数 的名字。