Django表单使用jQuery动态双列表框提交时字段校验报错如何解决
问题原因及修复方案
核心错误原因
你的校验报错是Django表单字段规则导致的,和插件本身无关:
Django的ModelMultipleChoiceField在校验提交值时,会强制验证提交的选项ID是否落在字段指定的queryset范围内。你给selected_stations设置的queryset=Station.objects.none(),相当于告诉Django这个字段没有合法可选值,所以哪怕前端把ID为22的选项移到了右侧框,后端校验也会直接判定非法。
修复步骤
1. 调整views.py校验逻辑(最安全方案)
POST请求接收参数时,动态给selected_stations字段赋值合法queryset,既能通过校验,也能避免用户恶意提交不存在的站点ID:
from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import VdlForm from station.models import Station def new_vdl(request): template_name = 'vdl.html' heading_message = 'Add a new vdl' if request.method == 'POST': form = VdlForm(request.POST or None) # 动态给selected_stations字段设置合法的queryset form.fields['selected_stations'].queryset = Station.objects.all() if form.is_valid(): vdl_name = form.cleaned_data.get("vdl_name") selected_stations = form.cleaned_data.get("selected_stations") # 此处补充你自己的业务存储逻辑 return HttpResponseRedirect('new_vdl') else: form = VdlForm() return render(request, template_name, {'form': form, 'heading': heading_message, })
2. 补充前端提交逻辑
你使用的双列表插件默认不会自动给右侧所有option加selected属性,只有手动选中的右侧选项才会被提交,所以需要增加提交前自动全选右侧选项的逻辑,修改vdl.html的脚本部分:
<script> $(".jp-multiselect").jQueryMultiSelection(); // 表单提交前自动选中右侧列表所有选项,保证全部提交到后端 $("form").submit(function(){ $("#id_selected_stations option").prop("selected", true); }); </script>
可选优化
如果不需要左侧stations字段提交到后端,可以给它的widget加disabled属性或者隐藏,减少无效参数传输,修改forms.py对应字段配置即可:
stations = forms.ModelMultipleChoiceField(queryset=station_all, widget=forms.SelectMultiple(attrs={'style': 'display:none'}))
内容的提问来源于stack exchange,提问作者Giuseppe Ricci
相关产品推荐
相关产品推荐

