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

如何在Django Admin的list_display中引用反向外键关联?

问题

我的应用需随时支持新增语言或方言,不同语言/方言的文本需互译,因此将不同语言文本关联为“文本组”(即多语言翻译集合),模型定义如下:

class StringFamily(models.Model):
    id = models.AutoField(primary_key=True)
    # plus some other fields


class String(models.Model):
    id = models.AutoField(primary_key=True)

    # the reference to StringFamily
    family = models.ForeignKey(StringFamily, null=False, on_delete=models.CASCADE)

    # other important stuff
    language = models.ForeignKey(Language, on_delete=models.DO_NOTHING)
    dialect = models.ForeignKey(Dialect, null=True, on_delete=models.SET_NULL)
    text = models.TextField(null=False)

现有Element模型关联StringFamily:

class Element(models.Model):
    id = models.AutoField(primary_key=True)
    element_role = models.ForeignKey(ElementRole, null=False, on_delete=models.RESTRICT)
    string_family = models.ForeignKey(StringFamily, null=True, on_delete=models.SET_NULL)
    # plus more fields

希望在ElementAdmin的list_display中添加display_english_string字段展示英文文本,尝试代码如下:

class Element(models.Model):
    # first above code, then...
    def display_english_string(self) -> str:
        strings = self.string_family.strings # this is the reference I would like to work but doesn't
        english_string = strings.filter(language="eng").values("text")[0]
        return english_string

    display_english_string.short_description = 'English Text'

运行报错:AttributeError: 'StringFamily' object has no attribute 'string',请问如何实现该需求?

解决方案

1. 修正反向关联名称

Django外键的默认反向关联名称为模型名小写_set,String模型的外键指向StringFamily,所以正确的反向关联属性是string_set,而非自定义的strings。

2. 处理空值与异常

需考虑string_family为空、找不到对应英文文本的情况,避免抛出异常:

class Element(models.Model):
    # 原有模型代码...
    def display_english_string(self) -> str:
        if not self.string_family:
            return "-"
        # 使用正确的反向关联获取String集合
        english_entry = self.string_family.string_set.filter(language__code="eng").first()
        return english_entry.text if english_entry else "-"

    display_english_string.short_description = 'English Text'

注:假设Language模型用code字段存储语言标识(如"eng"),若使用名称字段匹配,改为language__name="English"即可。

3. 优化Admin查询性能(可选)

当Element列表数据量较大时,每次调用方法会触发额外数据库查询,可通过prefetch_related预加载关联数据提升性能:

from django.contrib import admin

class ElementAdmin(admin.ModelAdmin):
    list_display = ['id', 'element_role', 'display_english_string']
    
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # 预加载关联的StringFamily和对应的String对象
        qs = qs.prefetch_related('string_family', 'string_family__string_set')
        return qs

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:14:57