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

Django中如何生成仅初始化一次的固定随机QuerySet列表?

问题分析

你的核心问题是每次GET请求都会重新生成随机Exercise列表,原因是当前代码不管Session里有没有sentences,都会执行data = list(Exercise.objects.filter(...).order_by('?'))[:3]生成新的随机数据,然后覆盖Session中的sentences。

解决方案

只在Session中不存在sentences时,才生成随机数据并存入Session;后续请求直接读取Session中已有的数据即可。

修改后的代码
class ExerciseView(View):
    def get(self, request, **kwargs):
        # 仅当Session中没有sentences时,才生成随机数据
        if 'sentences' not in request.session:
            data = list(Exercise.objects.filter(topic_type__slug=kwargs['slug_exercise']).order_by('?'))[:3]
            sentences = {}
            for i in range(len(data)):
                sentences[i] = {
                    'sentence': data[i].sentence,
                    'correct_answer': data[i].correct_answer,
                    'translation': data[i].translation,
                    'initial_form': data[i].initial_form,
                    'second_part': data[i].second_part
                }
            # 将生成的句子字典存入Session
            request.session['sentences'] = sentences
            # 同时初始化length、sentence_id、score
            request.session['length'] = len(sentences)
            request.session['sentence_id'] = 0
            request.session['score'] = 0
        else:
            # 从Session读取已有数据
            sentences = request.session['sentences']
            length = request.session['length']
            id = request.session['sentence_id']
            score = request.session['score']

        # 检查是否完成训练
        if request.session['length'] == request.session['sentence_id']:
            # 训练完成后清空Session,方便下次重新开始
            del request.session['sentences']
            del request.session['length']
            del request.session['sentence_id']
            del request.session['score']
            return render(request, 'practice_cases/exercise.html', {
                'message': 'You have just completed the test!',
                'score': score,
                'length': length,
            })
        else:
            current_sentence = sentences[request.session['sentence_id']]
            context = {
                'sentence': current_sentence['sentence'],
                'form': ExerciseForm(),
                'score': request.session['score'],
                'length': request.session['length'],
                'translation': current_sentence['translation'],
                'correct_answer': current_sentence['correct_answer'],
                'second_part': current_sentence['second_part']
            }
            # 针对特定类型添加initial_form字段
            if 'adjectives' in kwargs['slug_exercise'] or 'possessives' in kwargs['slug_exercise']:
                context['initial_form'] = current_sentence['initial_form']
            
            return render(request, 'practice_cases/exercise.html', context)
关键改动说明
  • 条件触发数据生成:通过if 'sentences' not in request.session:控制仅首次请求时生成随机数据,后续请求直接复用Session中的内容。
  • 统一Session初始化:首次生成数据时直接设置Session的sentences、length、sentence_id、score,避免setdefault带来的逻辑模糊。
  • 训练完成清理Session:用户完成训练后删除Session相关数据,确保下次进入页面会重新生成新的随机列表。
  • 简化上下文逻辑:合并重复的上下文构建代码,减少冗余,同时保证特定类型的字段正确传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:40:18