Can "list_display" in a Django ModelAdmin display attributes of ForeignKey fields? Can "list_display" in a Django ModelAdmin display attributes of ForeignKey fields? python python

Can "list_display" in a Django ModelAdmin display attributes of ForeignKey fields?


As another option, you can do look ups like:

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'

Since Django 3.2 you can use display() decorator:

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


Despite all the great answers above and due to me being new to Django, I was still stuck. Here's my explanation from a very newbie perspective.

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 (Incorrect Way) - you think it would work by using 'model__field' to reference, but it doesn't

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

admin.py (Correct Way) - this is how you reference a foreign key name the Django way

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)

For additional reference, see the Django model link here


Like the rest, I went with callables too. But they have one downside: by default, you can't order on them. Fortunately, there is a solution for that:

Django >= 1.8

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

Django < 1.8

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