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

如何让Django-admin的@admin.display装饰器支持多列排序?

Django Admin 自定义全名字段并支持多字段排序

我有一个包含last_name和first_name字段的数据库模型,想要在Django Admin中显示“姓氏, 名字”格式的全名,并且该列支持按姓氏+名字排序。

用@admin.display装饰器实现时,只传入单个排序字段(如ordering="last_name")可以正常工作,但同姓用户的顺序会混乱。尝试传入列表或元组作为ordering参数(如ordering=["last_name", "first_name"])时,会抛出'tuple' object has no attribute 'startswith'错误。


方法1:升级到支持多字段ordering的Django版本

从Django 3.2开始,@admin.display的ordering参数支持传入字符串的元组/列表。如果你使用的是该版本及以上,直接使用元组(推荐,避免列表带来的潜在问题)即可:

@admin.display(description="全名", ordering=('last_name', 'first_name'))
def full_name(self, obj):
    return f"{obj.last_name}, {obj.first_name}"

方法2:旧版Django兼容方案(不升级版本)

如果无法升级Django,可通过重写ModelAdmin的get_ordering方法,手动处理自定义字段的排序逻辑:

class YourModelAdmin(admin.ModelAdmin):
    list_display = ('full_name', '其他字段')

    @admin.display(description="全名")
    def full_name(self, obj):
        return f"{obj.last_name}, {obj.first_name}"

    def get_ordering(self, request):
        # 获取当前排序参数,o是Django Admin默认的排序参数名
        order_param = request.GET.get('o')
        # 自定义字段在list_display中的索引,这里full_name是第0个元素
        full_name_index = str(self.list_display.index('full_name'))
        if order_param == full_name_index:
            # 升序:按last_name、first_name排序
            return ('last_name', 'first_name')
        elif order_param == '-' + full_name_index:
            # 降序:按last_name、first_name倒序
            return ('-last_name', '-first_name')
        # 其他情况使用默认排序
        return super().get_ordering(request)

说明

  • 方法1更简洁,是官方推荐的方式,优先考虑升级Django版本。
  • 方法2通过拦截排序请求,将自定义字段的排序映射到真实的模型字段,兼容旧版Django。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:05:28