好吧,我仍然对蒂姆埃德加的解决方案感到不满意,所以我一直在寻找。我想我找到了我要找的东西。'Form' 类有两个在这种情况下有用的未记录方法:'has_changed()' 和 '_get_changed_data'。
在 ModelFormSet 验证期间,每个表单都会检查“has_changed()”。如果表单未更改,则跳过验证并假定表单正确。同样,在 ModelFormSet 保存期间,save_new_objects 检查每个表单以查看它是否已更改。如果它没有更改,则不会保存表单。
所以我的解决方案是重写 has_changed() 方法,如果只有 'group' 属性发生了变化,并且所有其他字段都为空,则返回 False。这是我的实现:
class UsesIngredientForm(forms.ModelForm):
class Meta:
model = UsesIngredient
def has_changed(self, *args, **kwargs):
self._get_changed_data(*args, **kwargs)
# If group is in changed_data, but no other fields are filled in, remove group so
# the form will not be validated or saved
if 'group' in self._changed_data and len(self._changed_data) == 1:
contains_data = False
for name in ['ingredient', 'amount', 'unit']:
field = self.fields[name]
prefixed_name = self.add_prefix(name)
data_value = field.widget.value_from_datadict(self.data, self.files, prefixed_name)
if data_value:
contains_data = True
break
if not contains_data:
self._changed_data.remove('group')
return bool(self._changed_data)
希望这对将来的任何人都有帮助!
编辑:我编辑了这个答案以反映蒂姆埃德加斯的评论。我意识到这个实现仍然使用“私有”方法,但我还没有找到只使用公开记录的方法的更干净的实现。但也许这只是我自己的无能:)。