Django Admin TabularInline中自动补全字段仅首行生效如何解决
问题原因
Django Admin的TabularInline每一行表单元素的id、name都会自动带上行号后缀(比如第一行是id_xxx_set-0-site_address,第二行是id_xxx_set-1-site_address),你硬编码了固定id,导致所有行的字段id重复,jQuery选择器永远只会匹配到第一个出现的id对应元素,所以修改的永远是第一行的地址。
解决方案
第一步:修改表单字段定义
删掉硬编码的固定id,同时将onchange参数改为传递当前触发元素本身而非仅传值:
self.fields['sites'].widget = forms.Select( attrs = { 'onchange': 'getsiteaddress(this)', 'style': 'width:200px' }, choices = sites_list, ) self.fields['site_address'].widget = forms.TextInput( attrs = { 'style': 'width:200px' } )
第二步:修改JS逻辑,按行定位元素
通过当前触发的下拉框找到所属的当前行,再在该行内匹配地址输入框:
function getsiteaddress(selectEl) { let $ = django.jQuery; // 定位当前操作的行 const currentRow = $(selectEl).closest('.form-row'); // 在当前行内查找地址输入框,用name模糊匹配适配行号后缀 const addressInput = currentRow.find('input[name*="site_address"]'); $.get('/Delivery/deploymentsite/'+ selectEl.value, function(resp) { addressInput.val(resp.data) }); }
可选优化(更规范的实现)
你也可以去掉inline的onchange绑定,改用事件委托,自动适配动态新增的inline行:
// 无需在widget中定义onchange,直接全局绑定事件 django.jQuery(document).on('change', 'select[name*="sites"]', function() { let $ = django.jQuery; const currentRow = $(this).closest('.form-row'); const addressInput = currentRow.find('input[name*="site_address"]'); $.get('/Delivery/deploymentsite/'+ this.value, function(resp) { addressInput.val(resp.data) }); })
内容的提问来源于stack exchange,提问作者The Experiment
相关产品推荐
相关产品推荐

