我正在尝试验证我的内联表单集成本值,以确保它总计为 100。表单集返回 5 次,因此应该添加 foreach 值,直到达到 100。如果大于或小于该值,则会显示错误并且不允许用户点击创建按钮。我正在尝试验证所有组合的表单而不是每个表单值。
模型.py
class EstimatedBudgetForm(forms.ModelForm):
def clean(self):
# get forms that actually have valid data
count = 0
for percentage in self.cost:
try:
if percentage.cleaned_data:
count += percentage
except AttributeError:
# annoyingly, if a subform is invalid Django explicity raises
# an AttributeError for cleaned_data
pass
if count != 100:
raise forms.ValidationError('Percentage must equal 100%')
Run Code Online (Sandbox Code Playgroud)
视图.py
EstimatedBudgetChildFormset = inlineformset_factory(
Project, EstimatedBudget, fields=('project', 'item', 'cost', 'time'), can_delete=False, form=EstimatedBudgetForm, extra=5, widgets={'item': forms.Select(attrs={'disabled': True})},
)
Run Code Online (Sandbox Code Playgroud)
要对表单集执行验证,应该重写clean表单集(而不是表单)的方法。对于内联表单集,您需要继承BaseInlineFormSet并使用它(有关更多信息,请参阅Overriding clean() on a ModelFormSet [Django docs]):
from django.forms import BaseInlineFormSet
class MyInlineFormset(BaseInlineFormSet):
def clean(self):
super().clean()
count = 0
for form in self.forms:
if not form.errors: # No need for a try-except, just check if the form doesn't have errors
count += form.cleaned_data['cost']
if count != 100: # This condition might not work if you are dealing with floating point numbers
raise forms.ValidationError('Percentage must equal 100%')
Run Code Online (Sandbox Code Playgroud)
接下来,在制作表单集时,指定formsetkwarg 而不是form:
EstimatedBudgetChildFormset = inlineformset_factory(
Project, EstimatedBudget, fields=('project', 'item', 'cost', 'time'), can_delete=False, formset=MyInlineFormset, extra=5, widgets={'item': forms.Select(attrs={'disabled': True})},
)
Run Code Online (Sandbox Code Playgroud)