您可以覆盖内联表单集以实现所需的功能。在表单集的clean方法中,您可以通过“实例”成员访问Shopping实例。因此,您可以使用购物模型暂时存储计算出的总数,并使表单集进行通信。在models.py中:
class Shopping(models.Model): shop_name = models.CharField(max_length=200) def __init__(self, *args, **kwargs) super(Shopping, self).__init__(*args, **kwargs) self.__total__ = None
在admin.py中:
from django.forms.models import baseInlineFormSetclass ItemInlineFormSet(baseInlineFormSet): def clean(self): super(ItemInlineFormSet, self).clean() total = 0 for form in self.forms: if not form.is_valid(): return #other errors exist, so don't bother if form.cleaned_data and not form.cleaned_data.get('DELETE'): total += form.cleaned_data['cost'] self.instance.__total__ = totalclass BuyerInlineFormSet(baseInlineFormSet): def clean(self): super(BuyerInlineFormSet, self).clean() total = 0 for form in self.forms: if not form.is_valid(): return #other errors exist, so don't bother if form.cleaned_data and not form.cleaned_data.get('DELETE'): total += form.cleaned_data['cost'] #compare only if Item inline forms were clean as well if self.instance.__total__ is not None and self.instance.__total__ != total: raise ValidationError('Oops!')class ItemInline(admin.TabularInline): model = Item formset = ItemInlineFormSetclass BuyerInline(admin.TabularInline): model = Buyer formset = BuyerInlineFormSet
这是您可以做到的唯一干净方法(据我所知),一切都放置在应有的位置。
编辑: 添加了 if form.cleaned_data 检查,因为表单也包含空内联。请让我知道它如何为您服务!
EDIT2: 添加了将要删除的表单的检查,如注释中正确指出的那样。这些表格不应参与计算。