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

如何在Django Forms中实现测验题选项随机排序?

解决Django表单中随机打乱选项的问题

问题根源

你当前的代码将Answer的QuerySet转为列表打乱后,直接赋值给ModelChoiceField的queryset属性——但queryset要求必须是Django的QuerySet对象,而非普通Python列表,这就是代码无效的原因。

两种可行解决方案

方案1:数据库层面随机排序(简单高效)

利用Django ORM的order_by('?')让数据库返回随机排序的结果,直接赋值给queryset:

from django import forms
from .models import Answer

class QuestionForm(forms.Form):
    selected_answer = forms.ModelChoiceField(
        queryset=Answer.objects.none(),
        widget=forms.RadioSelect,
        empty_label=None
    )

    def __init__(self, *args, question=None, **kwargs):
        super().__init__(*args, **kwargs)
        if question:
            # 数据库层面随机排序选项
            self.fields['selected_answer'].queryset = question.answer_set.order_by('?')

注意:order_by('?')在MySQL等数据库中,当选项数量极大时性能会有所下降,此时建议用方案2。

方案2:Python层面打乱后赋值给choices属性

将QuerySet转为列表打乱,生成符合要求的choices元组(格式为(对象ID, 显示文本)),赋值给字段的choices属性,同时保留原QuerySet用于表单验证:

from django import forms
from .models import Answer
import random

class QuestionForm(forms.Form):
    selected_answer = forms.ModelChoiceField(
        queryset=Answer.objects.none(),
        widget=forms.RadioSelect,
        empty_label=None
    )

    def __init__(self, *args, question=None, **kwargs):
        super().__init__(*args, **kwargs)
        if question:
            answers = list(question.answer_set.all())
            random.shuffle(answers)
            # 生成choices元组,需根据你的Answer模型实际显示字段调整(比如ans.text)
            self.fields['selected_answer'].choices = [(ans.id, ans.text) for ans in answers]
            # 保留原QuerySet确保表单验证时能识别有效答案ID
            self.fields['selected_answer'].queryset = question.answer_set.all()

视图与模板无需修改

你现有的views.py和template.html代码逻辑正确,保持原样即可——表单初始化时传入question参数后,就能渲染出随机排序的选项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:55:06