django-smart-selects配合jquery.formset.js动态行联动失效问题求助
问题原因
- django-smart-selects的联动初始化逻辑仅在页面DOM首次加载完成时执行,只会给当时已存在的联动字段绑定change事件
- 使用jquery.formset动态新增的表单行是后续插入DOM的,这些新行里的
ChainedForeignKey字段没有被初始化,因此联动失效 - 删除首行后重新新增的行同理,也没有触发smart-selects的初始化逻辑,所以功能失效
解决方案
步骤1:加载Formset的静态资源
你当前仅加载了主表单的media资源,需要补充加载formset的media,确保smart-selects的核心JS方法全局可用,在模板invoice_form.html的表单开头修改media加载部分:
{% csrf_token %} {{ form.media }} {{ items.media }} <!-- 新增这行,加载formset中字段的静态资源 -->
步骤2:新增formset行插入后的回调逻辑
修改custom_js块中的formset初始化代码,新增added回调,每次插入新行后手动初始化该行的smart-selects联动字段:
$(function() { $(".items-group").formset({ prefix: '{{ items.prefix }}', deleteText: "<div class='btn btn-danger btn-circle'><i class='fas fa-trash'></i></div>", addText: "<div class='btn btn-success btn-circle' style='text-align: center; margin-bottom: 10px;'><i class='fas fa-plus'></i></div>", // 新增以下回调逻辑 added: function(newRow) { // 初始化新行中的所有联动字段 newRow.find('select[data-chained]').each(function() { // 移除初始化标记,避免重复绑定事件 $(this).removeData('chained'); // 调用smart-selects全局方法初始化联动,版本兼容可二选一 if (window.init_chained_field) { window.init_chained_field($(this)); } // 若上面方法不生效,替换为下面的全局重新初始化方法即可 // if (window.bind_chained_fields) { // window.bind_chained_fields(); // } }); } }) })
可选优化:避免编辑状态下的联动冲突
你当前在表单中给已存在的实例的price字段加了disabled属性,可补充在初始化的时候跳过已禁用的字段,避免不必要的绑定,修改added回调中的判断逻辑即可:
if (!$(this).is(':disabled') && window.init_chained_field) { window.init_chained_field($(this)); }
验证方法
修改完成后测试以下场景:
- 直接新增多行,选中不同产品,价格字段联动正常
- 删除所有行后再新增,联动功能正常
- 编辑已有发票时,原有行的价格字段保持禁用,新增行联动正常
内容的提问来源于stack exchange,提问作者Kobby Essien
相关产品推荐
相关产品推荐

