Django如何获取<li>下拉选中项传递到视图并插入数据库
错误原因
- 直接原因:视图中读取的字段名和模板中定义的不一致。模板里隐藏输入框的
name属性是type_field,但你在views.py中用request.POST['typefield']取值,少了下划线,Django在POST数据里找不到对应的键就会抛MultiValueDictKeyError。 - 根本原因:下拉菜单的选中值没有正确绑定到表单提交的字段上。你把隐藏输入框写在了每个
<li>标签内部,既没有给输入框赋值,也没有和MDC Select的选中状态做联动,就算字段名对了也拿不到正确的选中项ID。
修复步骤
1. 修改HTML模板
首先调整下拉菜单结构,正确绑定选中值:
<form method="post" > {% csrf_token %} <!-- 新增全局隐藏输入框,用来提交选中的费用类型ID --> <input type="hidden" name="type_field" id="selected_type_id" value=""> <div class="template-demo" > <div class="mdc-select demo-width-class" data-mdc-auto-init="MDCSelect" id="type_select"> <i class="mdc-select__dropdown-icon"></i> <div class="mdc-select__selected-text"></div> <div class="mdc-select__menu mdc-menu-surface demo-width-class" > <ul class="mdc-list"> <li class="mdc-list-item mdc-list-item--selected" data-value="" aria-selected="true"> </li> {% for TypeFrais in typefrais %} <!-- 给li加data-value属性,绑定费用类型的主键ID --> <li class="mdc-list-item" data-value="{{ TypeFrais.FRT_ID }}"> {{TypeFrais.FRT_NAME}} </li> {% endfor%} </ul> </div> <span class="mdc-floating-label">Type de frais</span> <div class="mdc-line-ripple"> </div> </div> </div> <button class="mdc-button mdc-button--raised" type="submit"> Ajouter </button> </form> <!-- 新增JS监听选中事件,同步值到隐藏输入框 --> <script> const selectElement = document.getElementById('type_select'); const select = new mdc.select.MDCSelect(selectElement); select.listen('MDCSelect:change', () => { document.getElementById('selected_type_id').value = select.value; }); </script>
2. 修改views.py代码
修正读取字段的名称,和模板的name属性保持一致:
if request.method == 'POST': designation = request.POST['des_field'] date = request.POST['date_field'] montant = request.POST['montant_field'] # 修正字段名,和模板的name保持一致 type_id = request.POST['type_field'] GES_FRAIS = Frais(FR_TYPE_id=type_id,FR_DESIGNATION=designation,FR_MONTANT=montant,FR_DATE=date,FR_CODE=78) GES_FRAIS.save() return render(request, 'gesfrais.html',context)
优化建议
可以用request.POST.get('type_field')替代直接键取值,避免字段不存在时直接抛出异常,还可以加非空判断逻辑:
type_id = request.POST.get('type_field') if not type_id: # 可以返回错误提示给前端,告知用户需要选择费用类型 context['error_msg'] = '请选择费用类型' return render(request, 'gesfrais.html',context)
内容的提问来源于stack exchange,提问作者mohammed yazid Berrached
相关产品推荐
相关产品推荐

