如何在Django中实现测验答案顺序随机化?
在Django中实现测验答案的随机排序
下面提供几种可行的实现方案,按需选择即可:
方案一:修改模型方法直接返回随机排序的答案
直接修改Questions模型的关联方法,让它默认返回随机顺序的答案:
# models.py class Questions(models.Model): question = models.CharField(max_length=264, unique=True) point = models.PositiveIntegerField() def questionanswers(self): # 添加上order_by('?')实现随机排序 return self.question_answers.all().order_by('?') def __str__(self): return self.question class Answers(models.Model): question_id = models.ForeignKey(Questions, on_delete=models.CASCADE, related_name='question_answers') answer = models.CharField(max_length=20) is_true = models.BooleanField() def __str__(self): return self.answer
模板代码无需修改,依然使用原循环逻辑即可。
- 优点:改动最小,无需调整视图和模板
- 缺点:每次调用该方法都会触发一次数据库查询,问题数量较多时可能有性能损耗
方案二:在视图层预取并打乱答案(推荐)
通过预取关联数据减少数据库查询,在内存中完成随机排序,性能更优:
# views.py import random def your_view(request): # 用prefetch_related批量预取所有关联答案,减少数据库查询次数 question_list = Questions.objects.all().order_by('?')[:6].prefetch_related('question_answers') # 遍历每个问题,打乱答案顺序并挂载到问题对象上 for question in question_list: answers = list(question.question_answers.all()) random.shuffle(answers) question.shuffled_answers = answers context['questions'] = question_list return render(request, 'your_template.html', context)
修改模板代码,循环打乱后的答案列表:
{% for question in questions %} <div> <ol> {% for answer in question.shuffled_answers %} <li class="col-sm-6" style="margin-bottom: 10px"> <button class="btn btn-primary" type="button" id="{{answer.id}}" value="{{answer.id}}">{{answer}}</button> </li> {% endfor %} </ol> </div> {% endfor %}
- 优点:仅触发两次数据库查询(一次取问题、一次取所有关联答案),性能更优
- 缺点:需要同时修改视图和模板代码
方案三:模板层使用随机过滤器(不推荐)
借助Django内置的humanize标签在模板中实现随机排序,仅适合简单场景:
- 先在
settings.py中启用humanize应用:
INSTALLED_APPS = [ # ...其他应用 'django.contrib.humanize', ]
- 在模板顶部加载标签:
{% load humanize %}
- 修改循环逻辑:
{% for answer in question.questionanswers.all|random %} <li class="col-sm-6" style="margin-bottom: 10px"> <button class="btn btn-primary" type="button" id="{{answer.id}}" value="{{answer.id}}">{{answer}}</button> </li> {% endfor %}
- 优点:无需修改模型和视图
- 缺点:模板中掺杂业务逻辑,不利于维护和调试,性能不如视图层处理
内容的提问来源于stack exchange,提问作者ashraf sadik
相关产品推荐
相关产品推荐

