Flask如何将多选框选中项存入多对多关联数据库
解决方案
核心原理
Flask-SQLAlchemy 会自动维护多对多关系的中间关联表,不需要手动往formula_hazards表插入数据,只需要给模型里定义的关系字段绑定对应的模型对象列表,提交会话时ORM会自动完成中间表的写入。
第一步:修复前端JS高频踩坑点
双多选框移动选项时,必须保证移动到「Selected」框内的所有<option>都带有selected属性,移回可选框时取消该属性,否则表单提交时不会携带这些选项的值,后端getlist会拿到空列表。
参考JS实现:
function leftHazard() { const availableBox = document.getElementById('hazard-options'); const selectedBox = document.getElementById('hazard-selected'); Array.from(availableBox.selectedOptions).forEach(option => { option.selected = true; selectedBox.appendChild(option); }); } function rightHazard() { const availableBox = document.getElementById('hazard-options'); const selectedBox = document.getElementById('hazard-selected'); Array.from(selectedBox.selectedOptions).forEach(option => { option.selected = false; availableBox.appendChild(option); }); }
第二步:修改后端写入逻辑
拿到前端传的已选hazard ID列表后,查询出对应的模型对象,直接赋值给Formula实例的关系字段即可,修正后的路由代码如下:
@admin.route('/admin/formulas/add', methods=['GET', 'POST']) @login_required def formulaadd(): if is_super(): formula_form = FormulaForm() hazard_list = HazardStatements.query.order_by(HazardStatements.h_code).all() if request.method == 'POST' and formula_form.validate_on_submit(): new_formula = Formula( number = formula_form.number.data, signal_word = formula_form.signal_word.data, ) # 提取已选hazard的ID,转为整数 selected_hazard_ids = [int(hid) for hid in request.form.getlist('hazard-selected')] # 批量查询对应的危险说明对象 selected_hazards = HazardStatements.query.filter( HazardStatements.id.in_(selected_hazard_ids) ).all() # 绑定多对多关系,ORM会自动写入中间关联表 new_formula.h_rel = selected_hazards db.session.add(new_formula) db.session.commit() flash('Formula has been added', category='success') return redirect(url_for('admin.formulaview')) return render_template('/admin/formulas/formula_add.html', title="Add Formula", formula_form=formula_form, hazard_list=hazard_list)
可选优化建议
当前模型里的反向引用命名h_rel语义不清晰,建议修改为更易读的名称,方便后续反向查询:
# 原代码 h_rel = db.relationship('HazardStatements', secondary=formula_hazards, backref='h_rel') # 修改后,反向查询某个HazardStatement关联的所有Formula时直接用 hazard.formulas 即可 h_rel = db.relationship('HazardStatements', secondary=formula_hazards, backref='formulas')
内容的提问来源于stack exchange,提问作者Pixelope
相关产品推荐
相关产品推荐

