Django动态添加formset时报NoneType与int无法比较错误如何解决
解决方案
报错原因
你遇到的报错是因为JS中form计数逻辑错误,提交的TOTAL_FORMS数值比实际渲染的表单数量多1,后端校验时找不到对应索引的表单数据,传入了None作为index参数,触发了类型比较错误。
修复步骤
1. 修正JS计数逻辑
修改add_more_ingredients.js代码,修正计数和TOTAL_FORMS赋值逻辑,同时补全函数闭合括号:
let addIngButton = document.querySelector("#add_more_ingredients") addIngButton.addEventListener('click', addIngForm) function addIngForm(e) { e.preventDefault() // 新增表单的索引直接使用当前计数 let newFormIndex = ingFormCount ingFormCount++ // 总表单数直接等于更新后的计数,无需额外+1 let totalForms = document.getElementById("id_ingredients-TOTAL_FORMS") totalForms.value = ingFormCount let ingredientForm = document.querySelector("#ingredientform") let ingContainer = document.createElement('div'); ingContainer.classList.add('ingredientinfo'); ingContainer.insertAdjacentHTML("beforeend", emptyIngForm.replace(/__prefix__/g, newFormIndex)) ingredientForm.appendChild(ingContainer) }
2. 按需隐藏删除复选框
无需修改formset的can_delete全局配置,通过表单初始化参数区分创建/编辑场景即可:
修改forms.py代码
class IngredientForm(forms.ModelForm): class Meta: model = Ingredient exclude = ['recipe',] def __init__(self, *args, **kwargs): # 接收隐藏删除字段的参数 hide_delete = kwargs.pop('hide_delete', False) super().__init__(*args, **kwargs) if hide_delete and 'DELETE' in self.fields: del self.fields['DELETE'] IngredientFormSet = inlineformset_factory( RecipeCard, Ingredient, form = IngredientForm, can_delete = True, extra=2, max_num=15 )
视图层传参控制
- 创建食谱的视图中,传入
hide_delete=True隐藏删除框:
# 创建页视图示例 iformset = IngredientFormSet( request.POST or None, form_kwargs={'hide_delete': True} )
- 编辑食谱的视图中,无需传参,删除框正常显示,支持删除已有食材:
# 编辑页视图示例 iformset = IngredientFormSet( request.POST or None, instance=当前编辑的RecipeCard实例 )
可选优化方案
如果不想手动维护JS逻辑,可以直接使用封装好的动态formset第三方库,无需自己写JS逻辑,配置即可实现新增、删除、排序功能。
内容的提问来源于stack exchange,提问作者Loz
相关产品推荐
相关产品推荐

