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

Django Admin未调用模型中重写的_get_FIELD_display方法问题

Django Admin未调用重写的get_FIELD_display方法的解决办法

问题分析

你在模型X中重写了get_status_display()方法,用于将DELIVERED状态的显示文本替换为Completed!,该方法在序列化器中正常工作,但Django Admin并未调用它,原因可能是:

  • 你使用的FSMField是自定义字段(来自django-fsm),Django Admin对这类字段的默认处理逻辑是直接读取字段本身的choices属性,而非调用模型的get_FIELD_display()方法;
  • 模型代码中存在笔误:get_status_display里引用了Order.STATUSES,但当前模型是X,这会导致方法执行出错,Admin自动 fallback 到默认的choices显示。

解决方案

1. 修正模型中的笔误

首先把模型里的Order.STATUSES替换为X.STATUSES,确保方法能正常执行:

def get_status_display(self) -> str:
    """ Overrides to replace X.STATUSES.DELIVERED with Completed as it's confusing."""
    value = self.status
    if value == X.STATUSES.DELIVERED:
        return _("Completed!")
    choices_dict = dict(X.STATUSES)
    # force_str() to coerce lazy strings.
    return force_str(choices_dict[value], strings_only=True)

2. 在ModelAdmin中显式调用自定义显示方法

如果是Admin列表页不显示自定义文本,在ModelAdmin的list_display中使用自定义函数,显式调用模型的get_status_display():

from django.contrib import admin
from .models import X

class XAdmin(admin.ModelAdmin):
    # 替换原有的'status'为自定义显示函数
    list_display = ('id', 'custom_status', 'created', 'modified')

    def custom_status(self, obj):
        return obj.get_status_display()
    # 设置列表页表头名称
    custom_status.short_description = 'Status'

admin.site.register(X, XAdmin)

3. 适配详情编辑页的显示

如果需要在Admin的详情编辑页也显示自定义文本(由于status字段设置了protected=True,通常为只读状态),可以添加只读字段并绑定自定义显示:

class XAdmin(admin.ModelAdmin):
    list_display = ('id', 'custom_status', 'created', 'modified')
    readonly_fields = ('custom_status',)
    # 替换原有'status'字段为自定义只读字段
    fields = ('custom_status', 'created', 'modified')

    def custom_status(self, obj):
        return obj.get_status_display()
    custom_status.short_description = 'Status'

4. 动态修改表单choices(如需保留编辑权限)

如果需要保留status字段的编辑权限(尽管protected=True可能限制状态转换),可以自定义ModelForm来动态修改choices:

from django import forms
from django.contrib import admin
from .models import X

class XAdminForm(forms.ModelForm):
    class Meta:
        model = X
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 遍历choices,替换DELIVERED的显示文本
        updated_choices = []
        for value, label in self.fields['status'].choices:
            if value == X.STATUSES.DELIVERED:
                updated_choices.append((value, _("Completed!")))
            else:
                updated_choices.append((value, label))
        self.fields['status'].choices = updated_choices

class XAdmin(admin.ModelAdmin):
    form = XAdminForm
    list_display = ('id', 'get_status_display', 'created', 'modified')

admin.site.register(X, XAdmin)

内容的提问来源于stack exchange,提问作者Ibrahim Abou Elenein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:27:04