Django Manytomany through表list_display按资质分组去重展示关联单元问题
解决方案
核心思路:按bridge_qual_id分组,聚合同一资质下的所有关联单元和对应顺序,在admin列表页每行展示一个资质及对应的全部单元数据。
原代码错误说明:
extra方法的where参数只能写条件语句,不能放置GROUP BY、ORDER BY等子句,语法逻辑错误- 没有对
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
相关产品推荐
相关产品推荐

