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

Django循环中获取唯一Question值:distinct()失效求助

解决Django中Question去重问题

问题分析

你当前的写法里,distinct() 完全起不到全局去重的作用——因为每次循环都是单独查询当前主题下的问题,且仅取第一个随机结果,既没有排除之前已经选中的问题,distinct() 也只是对单次查询的结果去重(而单次查询的结果本身就是唯一的Question ID,所以这个调用毫无意义)。最终导致同一个Question可能被多次选中加入questions_list。

解决方案

核心思路是记录已选中的Question ID,每次查询时排除这些ID,同时批量获取每个主题需要的问题数量,避免循环多次查询提升效率:

subject = QuestionSubject.objects.get(id=request.POST.get('subject'))
question_topics = QuestionTopic.objects.filter(question_subject=subject)            
questions_list = []
selected_ids = set()  # 用集合存已选ID,查询排除时效率更高

for topic in question_topics:
    need_count = topic.exam_questions_num
    if not need_count:
        continue  # 如果不需要取该主题的问题,直接跳过
    
    # 查询当前主题下、未被选中的问题,随机排序后取指定数量
    selected_questions = Question.objects.filter(
        question_subject=subject,
        question_topic=topic,
        id__notin=selected_ids
    ).order_by('?')[:need_count].values_list('id', flat=True)
    
    # 将结果加入列表和已选集合
    questions_list.extend(selected_questions)
    selected_ids.update(selected_questions)

关键说明

  • 使用set存储已选ID:集合的查询效率远高于列表,用id__notin=selected_ids排除已选问题时性能更好。
  • 批量获取问题:直接通过切片[:need_count]一次获取需要的数量,替代循环多次查询,减少数据库交互次数。
  • 处理边界情况:如果某个主题下的可用问题数量少于exam_questions_num,切片会自动取所有剩余问题,不会抛出异常。

为什么原代码的distinct()无效?

原代码中distinct()作用于单次查询的结果集,但Question的id是主键本身就唯一,单次查询的结果集里不会有重复ID,所以这个调用完全多余。而且每次查询没有排除之前选中的ID,所以重复选中同一个Question的概率很高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:31:37