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

Django Manytomany through表list_display按资质分组去重展示关联单元问题

解决方案

核心思路:按bridge_qual_id分组,聚合同一资质下的所有关联单元和对应顺序,在admin列表页每行展示一个资质及对应的全部单元数据。


原代码错误说明:

  1. extra方法的where参数只能写条件语句,不能放置GROUP BY、ORDER BY等子句,语法逻辑错误
  2. 没有对bridge_qual_id做分组聚合,必然会导致每条中间表记录单独展示,出现重复资质

步骤1:修正QuerySet实现分组聚合

你使用的是MySQL数据库,直接用GROUP_CONCAT聚合函数拼接同一资质下的单元和顺序,避免用已废弃的extra方法:

from django.db.models import Func, Value
from django.db.models.functions import Concat

# 自定义MySQL GROUP_CONCAT聚合函数适配
class GroupConcat(Func):
    function = 'GROUP_CONCAT'
    template = '%(function)s(%(expressions)s SEPARATOR "、")'

@admin.register(tp_uoc_sequence, site=pg_site)
class tpuocAdmin(admin.ModelAdmin):
    # 移除单独的bridge_uoc字段,改用自定义聚合字段
    list_display = ['bridge_qual', 'related_uoc_with_sequence']

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # 按资质分组,聚合关联单元和对应交付顺序
        qs = qs.values('bridge_qual_id', 'bridge_qual').annotate(
            # 拼接格式为:单元名称(交付顺序),可按需调整字段
            uoc_list=GroupConcat(
                Concat('bridge_uoc', Value('('), 'uoc_sequence', Value(')'))
            )
        ).order_by('bridge_qual_id') # 直接指定排序字段即可
        return qs

步骤2:自定义列表字段展示聚合内容

新增admin方法渲染聚合后的关联单元数据:

def related_uoc_with_sequence(self, obj):
        # 如果需要渲染成HTML格式(比如换行、加样式),配合format_html使用即可
        return obj['uoc_list']
    # 给自定义字段设置表头展示名称
    related_uoc_with_sequence.short_description = '关联单元(交付顺序)'

如果之前用format_html_join没有生效,是因为你没有先对QuerySet做分组,还是按单条中间表记录渲染,自然会重复显示资质。

内容的提问来源于stack exchange,提问作者G-2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:21:00