如何在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
相关产品推荐
相关产品推荐

