You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Admin含多个同模型外键的模型无法显示关联属性如何解决

错误成因

Django Admin 的 list_display 配置项本身不支持直接使用双下划线__的跨模型关联查询语法,你之前在单个外键场景下的正常生效属于误记,大概率是之前的场景中额外定义了对应的属性/方法才支持了该写法。
Django 在校验list_display的取值时,只会检查三类目标:当前TypeAdmin类的属性/方法、Type模型的属性/方法、可调用对象,icon1__name不属于上述三类,因此直接抛出admin.E108错误。

修复方案

有两种常用的修复方式,都可以兼容外键为空的场景:

方案1:在ModelAdmin中自定义展示方法(推荐)

直接在TypeAdmin类中定义获取关联图标名称的方法,同时处理空值情况:

class TypeAdmin(admin.ModelAdmin):
    list_display = (
        'name',
        'get_icon1_name',
        'get_icon2_name',
        'get_icon3_name',
        'modified_date',
        'creation_date',
        'id'
    )
    # 联表提前查询关联Icon,避免N+1查询问题
    list_select_related = ('icon1', 'icon2', 'icon3')

    def get_icon1_name(self, obj):
        # 外键为空时返回横杠占位
        return obj.icon1.name if obj.icon1 else '-'
    # 自定义列表页的列头显示名称
    get_icon1_name.short_description = '图标1名称'

    def get_icon2_name(self, obj):
        return obj.icon2.name if obj.icon2 else '-'
    get_icon2_name.short_description = '图标2名称'

    def get_icon3_name(self, obj):
        return obj.icon3.name if obj.icon3 else '-'
    get_icon3_name.short_description = '图标3名称'

admin.site.register(models.Type, TypeAdmin)

方案2:在Type模型中定义关联属性

如果需要在Admin之外的场景也能直接获取图标名称,可以把属性定义在Type模型中:
首先修改models.py的Type类:

class Type(models.Model):
    name = models.CharField(max_length=60)
    modified_date = models.DateTimeField(auto_now=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    icon1 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon1")
    icon2 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon2")
    icon3 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon3")

    def __str__(self):
        return self.name

    @property
    def icon1_name(self):
        return self.icon1.name if self.icon1 else '-'

    @property
    def icon2_name(self):
        return self.icon2.name if self.icon2 else '-'

    @property
    def icon3_name(self):
        return self.icon3.name if self.icon3 else '-'

之后修改admin.py的list_display配置即可:

class TypeAdmin(admin.ModelAdmin):
    list_display = (
        'name',
        'icon1_name',
        'icon2_name',
        'icon3_name',
        'modified_date',
        'creation_date',
        'id'
    )
    list_select_related = ('icon1', 'icon2', 'icon3')

内容的提问来源于stack exchange,提问作者DDCA567

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:39:02