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

