我有一张由两种型号组成的发票表格 - 发票和发票。 InvoiceItem - 在inlineformset_factory的帮助下。
我有以下jquery片段,通过读取每个项目的价格,数量,税来计算个别总计和净总额。
function calculateSubTotal(obj){
subTotal = 0
parentDiv = obj.closest('.formset')
rate=parseFloat($(parentDiv).find('.rate').val())
quantity=parseInt($(parentDiv).find('.quantity').val())
tax=$(parentDiv).find('.tax option:selected').html()//.
tax=tax.match(/\d+/);
if(tax)
tax=parseFloat(tax[0],10)
else
return
if(!isNaN(rate) && !isNaN(quantity) && $.isNumeric(tax)){
subTotal = rate*quantity*(100+tax)/100
$(parentDiv).find('.total').val(subTotal)
}
}
function calculateTotal() {
subTotal=0
$('.total').each(function(){
//console.log($(this).id)
console.log($(this).val())
val=parseFloat($(this).val())
subTotal+=val
});
if(!isNaN(subTotal))
$('#id_total').val(subTotal)
}
$(document).ready(function() {
$('.formset .form-control').on("blur",function(e){
calculateSubTotal(this);
calculateTotal();
});
});
现在,我“相信”,我需要在保存之前在服务器端进行所有这些计算,以防止用户在表单中进行任何手动更正/错误。 (如果我错了,请纠正我)
我如何继续?
这是我的CreateView的form_valid()。
def form_valid(self, form):
context = self.get_context_data()
item_formset = context['item_formset']
with transaction.atomic():
form.instance.invoice_type=self.kwargs['invoice_type']
self.object = form.save(commit=False)
#self.object.save()
if item_formset.is_valid():
forms = item_formset.save(commit=False)
for form in forms:
**#calculate sub-total and assign net-total to parentform.instance.total**
item_formset.instance = self.object
item_formset.save()
return super().form_valid(form)
答案 0 :(得分:0)
最干净的方法可能是为Invoice
和InvoiceItem
创建自定义模型方法,然后在表单上save()
或在您的视图{{1}中调用它们}}
示例form_vaild()
:
models.py
然后在class Invoice(models.Model):
customer = models.ForeignKey()
date = models.DateField()
total = models.DecimalField()
def process_invoice(self):
items = InvoiceItem.objects.filter(invoice=self)
for item in items:
... process item ....
item.save()
self.total = InvoiceItem.objects.filter(invoice=self).values('line_total').aggregate(tot=Sum('line_total')['tot']
... add whatever other logic you need ...
self.save()
中,您可以通过form_valid
调用该方法。
答案 1 :(得分:0)
围绕模型的大量试验和错误保存(),保存后信号,形成干净()等等,最后得到了一些有用的东西。
以下是它现在的样子。
首先,使用InvoiceItemForm
的{{1}}方法确保每行的总数正确
def clean(self): cleaning_data = super(InvoiceItemForm,self).clean()
clean()
接下来,在CreateViews的form_valid()方法下,遍历formset中的每个表单并对各个总计求和。将其与主表单的总值进行比较。
with transaction.atomic(): form.instance.invoice_type = self.kwargs [' invoice_type'] self.object = form.save(commit = False)
total=cleaned_data.get('total')
if total:
tax=cleaned_data.get('tax')
calculated_total=price*(100+tax.rate)*quantity/100
if calculated_total != total:
raise forms.ValidationError({'total':["Total is incorrect."]})
return cleaned_data
(欢迎任何可能的更正/简化)
感谢。