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

如何在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标签在模板中实现随机排序,仅适合简单场景:

  1. 先在settings.py中启用humanize应用:
INSTALLED_APPS = [
    # ...其他应用
    'django.contrib.humanize',
]
  1. 在模板顶部加载标签:
{% load humanize %}
  1. 修改循环逻辑:
{% 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:01:34