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

Django中ModelMultipleChoiceField自定义渲染后无法提交选中值问题

Django表单自定义复选框无法提交数据的解决方法

问题场景

我需要创建一个表单,从数据库的students表中获取所有学生对象,让用户选择要发送邮件的学生。目前能正确显示对应数量的学生,但自定义渲染的复选框选中后无法提交数据,只有通过student.tag渲染的选项能正常提交选中信息。

原表单代码

class SendEmailStudentsForm(forms.Form):
    students = forms.ModelMultipleChoiceField(
        queryset=Students.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False)

原模板代码

<form action="#" method="post">
        {% csrf_token %}
        {% for student in form.students %}
            <ul>
            <li>{{ forloop.counter }} - {{ student.id }}</li>
            <li>Email: - {{ student.email }}</li>
            <li>Add student<input type="checkbox" id="{{ student.id }}"></li>
            <li>Add <span>{{ student.tag }}</span></li>
            </ul>
        {% endfor %}
        <button type="submit" class="btn btn-primary">Send emails</button>
        <a href="{% url 'students:index' %}" class="btn btn-primary">Back</a>
    </form>

原视图代码

def select_students_emails(request):
    if request.method == "POST":
        form = SendEmailStudentsForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data)
            # send_mail(...)
            return HttpResponseRedirect(reverse('students:index'))
    else:
        form = SendEmailStudentsForm()
        return render(request, 'students/select_students.html', context={'form': form})

问题原因

自定义的<input type="checkbox">缺少两个关键属性:

  • name属性:Django表单需要通过与字段名一致的name来识别提交的数据,这里字段名为students
  • value属性:需要设置为学生的主键ID,这样Django才能将提交的值与ModelMultipleChoiceField的查询集对象匹配

而student.tag是Django自动生成的表单元素,已经包含了正确的name="students"和value="学生ID"属性,所以能正常提交。

解决方案

修改模板中的自定义复选框,添加正确的name和value属性,同时修正学生属性的取值方式:

<form action="#" method="post">
    {% csrf_token %}
    {% for student in form.students %}
        <ul>
        <li>{{ forloop.counter }} - {{ student.id }}</li>
        <li>Email: - {{ student.choice_label.email }}</li>
        <li>
            Add student
            <input type="checkbox" id="id_students_{{ student.id }}" name="students" value="{{ student.id }}">
        </li>
        <li>Add <span>{{ student.tag }}</span></li>
        </ul>
    {% endfor %}
    <button type="submit" class="btn btn-primary">Send emails</button>
    <a href="{% url 'students:index' %}" class="btn btn-primary">Back</a>
</form>

修改说明

  1. 添加name属性:设置为name="students",与表单类中的字段名保持一致,确保Django能识别该字段的提交数据
  2. 添加value属性:设置为value="{{ student.id }}",对应学生的主键ID,让Django能匹配到对应的Students实例
  3. 修正学生属性取值:模板中的student是表单的选项对象(BoundChoice实例),学生的模型属性需要通过student.choice_label获取,比如student.choice_label.email
  4. 规范ID属性:将id设置为id_students_{{ student.id }},与Django自动生成的元素ID格式统一,避免冲突

修改完成后,提交表单时自定义复选框选中的学生数据会被正确识别,form.cleaned_data['students']会返回选中的Students实例集合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:23:13