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

如何在Django表单ModelChoiceField中查询展示关联字段值并去重

解决方案

场景1:字段仍存储Class实例ID,仅修改下拉选项显示文本+去重

你可以通过自定义ModelChoiceField的label_from_instance参数修改选项展示内容,再根据你使用的数据库选择去重方案:

方案A:PostgreSQL数据库(支持带字段的DISTINCT)

直接修改表单字段定义即可:

class OrganisorClassStatusUpdateForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['off_day_student'] = forms.ModelChoiceField(
            # 先按学生分组取最新的课程,再按日期降序排序
            queryset=Class.objects.filter(
                teacher=self.instance.teacher,
                is_new_set=True,
                time=self.instance.time
            ).order_by('student', '-date').distinct('student').order_by('-date')[:10],
            # 自定义选项显示为关联学生的内容,可替换为cls_obj.student.name等具体字段
            label_from_instance=lambda cls_obj: cls_obj.student.__str__()
        )

方案B:MySQL等不支持带字段DISTINCT的数据库

在Python层面按顺序去重:

class OrganisorClassStatusUpdateForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 先取原始符合条件的课程列表
        origin_classes = Class.objects.filter(
            teacher=self.instance.teacher,
            is_new_set=True,
            time=self.instance.time
        ).order_by('-date')[:10]
        # 按顺序去重学生
        exist_student_ids = set()
        filtered_class_ids = []
        for cls in origin_classes:
            if cls.student_id not in exist_student_ids:
                exist_student_ids.add(cls.student_id)
                filtered_class_ids.append(cls.pk)
        # 构造最终字段
        self.fields['off_day_student'] = forms.ModelChoiceField(
            queryset=Class.objects.filter(pk__in=filtered_class_ids).order_by('-date'),
            # 自定义选项显示为关联学生的内容,可替换为cls_obj.student.name等具体字段
            label_from_instance=lambda cls_obj: cls_obj.student.__str__()
        )

场景2:字段需要存储Student(即Lead模型)实例ID

如果你的off_day_student字段关联的是Lead模型,直接调整查询集为Lead模型即可:

from django.db.models import Max

class OrganisorClassStatusUpdateForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['off_day_student'] = forms.ModelChoiceField(
            # 筛选关联课程符合条件的学生,按最新课程日期降序排序去重
            queryset=Lead.objects.filter(
                student__teacher=self.instance.teacher,
                student__is_new_set=True,
                student__time=self.instance.time
            ).annotate(
                latest_class_date=Max('student__date')
            ).order_by('-latest_class_date').distinct()[:10]
        )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 20:06:02