如何在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配置(admin.py)
class BookAdmin(admin.ModelAdmin): list_display = ('title', 'characters', 'authors') def characters(self, obj): # 待实现 def authors(self, obj): # 待实现
核心实现逻辑
两个自定义列方法的入参obj,就是当前列表行对应的单条Book实例。由于模型定义时已经给关联字段配置了related_name,可以直接通过反向关联管理器拿到所有关联对象,把需要展示的字段拼接成可读字符串,就能在Admin列表页正常显示。
关联角色(外键反向关联)列实现
Character模型中指向Book的外键,设置了反向关联名related_name='character',因此可以通过obj.character查询到当前书籍绑定的所有角色对象:
def characters(self, obj): character_list = obj.character.all() if not character_list: return "暂无关联角色" return "、".join([char.name for char in character_list]) # 自定义列表头显示文案,替代默认生成的"Characters" characters.short_description = "关联角色"
关联作者(多对多反向关联)列实现
Author模型中指向Book的多对多字段,设置了反向关联名related_name='author',同理可以通过obj.author查询到当前书籍绑定的所有作者对象:
def authors(self, obj): author_list = obj.author.all() if not author_list: return "暂无关联作者" return "、".join([author.name for author in author_list]) authors.short_description = "关联作者"
性能优化提示
如果书籍数据量较大,逐行触发关联对象查询会产生N+1数据库查询问题,拖慢Admin列表加载速度。可以通过重写查询集方法提前预加载关联数据:
def get_queryset(self, request): queryset = super().get_queryset(request) # 预加载外键、多对多的关联集合,大幅减少查询次数 return queryset.prefetch_related('character', 'author')
内容的提问来源于stack exchange,提问作者vostbur
相关产品推荐
相关产品推荐

