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

如何在Django中从views.py向forms.ChoiceField传递选项实现在线测试表单

实现方案

核心思路是重写表单类的初始化方法,支持接收视图传递的动态参数,在表单初始化阶段给单选框字段赋值选项,不需要在forms.py中提前定义固定选项。

1. 编写动态选项表单(forms.py)

表单中单选字段的choices初始设为空列表,通过重写__init__方法接收视图传入的Course实例,从实例中提取测试题目选项,动态赋值给单选字段的choices参数:

from django import forms
from .models import Course

class TestForm(forms.Form):
    # 单选字段初始不设置固定选项
    test_answer = forms.ChoiceField(
        label="测试题答案",
        choices=[],
        widget=forms.RadioSelect  # 指定渲染为单选按钮
    )

    def __init__(self, *args, **kwargs):
        # 接收视图传入的course实例参数
        self.course = kwargs.pop('course', None)
        super().__init__(*args, **kwargs)
        if self.course:
            # 从course实例中提取Test1_1到Test1_5作为选项
            self.fields['test_answer'].choices = [
                (str(i), getattr(self.course, f'Test1_{i}'))
                for i in range(1, 6)
                if getattr(self.course, f'Test1_{i}').strip()  # 过滤空选项
            ]
            # 可选:把测试题目设为字段label
            self.fields['test_answer'].label = self.course.Test1

2. 视图层传递动态参数(views.py)

无论是GET请求首次加载表单,还是POST请求提交后做表单校验,都需要先查询到对应的Course实例,再将实例传入表单的初始化参数中:

from django.shortcuts import render, get_object_or_404
from .models import Course
from .forms import TestForm

def course_test(request, course_slug):
    # 根据url传入的slug查询对应的课程实例
    course = get_object_or_404(Course, slug=course_slug)
    if request.method == 'POST':
        # POST请求校验时也要传入course参数
        form = TestForm(request.POST, course=course)
        if form.is_valid():
            selected_answer = form.cleaned_data['test_answer']
            # 此处添加答案校验、得分统计等业务逻辑
            return render(request, 'test_result.html', {'score': 100})
    else:
        # GET请求加载表单时传入course参数
        form = TestForm(course=course)
    return render(request, 'test_page.html', {'form': form, 'course': course})

3. 模板渲染示例(test_page.html)

正常渲染表单即可,单选按钮会自动加载从Course实例中提取的动态选项:

<!DOCTYPE html>
<html>
<head>
    <title>{{ course.title }}测试</title>
</head>
<body>
    <h1>{{ course.title }}</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">提交答案</button>
    </form>
</body>
</html>

注意事项

  • 如果需要支持多道测试题,可以在表单的__init__方法中循环生成多个ChoiceField字段,适配不同的测试题数量
  • POST请求必须传入course参数,否则表单初始化时没有选项数据,会触发校验错误
  • 若选项存储结构调整,只需要修改表单__init__中组装choices的逻辑即可,不需要改动视图层代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 11:36:10