Django 根据表单集中的两个字段计算字段

1 投票
1 回答
1829 浏览
提问于 2025-04-28 09:49

我有两个表单,分别是OrderHeaderForm和OrderLineForm。OrderHeaderForm用来显示客户信息和总价格,而OrderLineForm是一个表单集合,显示产品、数量、价格和小计。

我想计算OrderLineForm中每一行的总价(数量乘以价格)。最好是在数量或价格调整时能够自动重新计算总价,但我不知道该怎么创建和显示这个计算。任何关于如何实现这个功能的建议都会非常感谢。

编辑:我已经让它工作了,下面是编辑后的代码,但我觉得这似乎是计算表单字段的一种“脏”方式。而且目前的计算只在提交后进行。有没有更干净或者实时的方法来做这个计算的建议?

models.py中的新代码:

def linetotalprice(self):
    linetotalprice = self.orderline_product_price * self.orderline_quantity
    return linetotalprice

views.py中的新代码:

if form.is_valid() and formset.is_valid():
    saveform = form.save(commit=False)
    saveform.save()
    formset.save()
    orderheader = OrderHeader.objects.get(pk=orderid.pk)
    orderlines = OrderLine.objects.filter(orderheader=orderid)
    orderheader.orderheader_total_price = 0
    for orderline in orderlines:  
        orderline.orderline_total_price = orderline.linetotalprice()
        orderheader.orderheader_total_price += orderline.linetotalprice()
        orderline.save()
        orderheader.save()

我的models.py:

class OrderHeader(models.Model):
    customer = models.ForeignKey(Customer)
    orderheader_total_price = models.DecimalField()

    def __unicode__(self):
        return smart_unicode(self.pk)

class OrderLine(models.Model):
    orderheader = models.ForeignKey(OrderHeader)
    product = models.ForeignKey(Product)
    material = models.ForeignKey(ProductMaterial)
    orderline_quantity = models.DecimalField()
    orderline_product_price = models.DecimalField()
    orderline_total_price = models.DecimalField()

    def __unicode__(self):
        return smart_unicode(self.pk)

    def linetotalprice(self):
        linetotalprice = self.orderline_product_price * self.orderline_quantity
        return linetotalprice

我的views.py:

if request.method == 'POST':
    form = OrderHeaderForm(request.POST, instance=orderid)
    formset = OrderLineFormSet(request.POST,instance=orderid)
    if form.is_valid() and formset.is_valid():
        form.save()
        formset.save()
        orderheader = OrderHeader.objects.get(pk=orderid.pk)
        orderlines = OrderLine.objects.filter(orderheader=orderid)
        orderheader.orderheader_total_price = 0
        for orderline in orderlines:  
            orderline.orderline_total_price = orderline.linetotalprice()
            orderheader.orderheader_total_price += orderline.linetotalprice()
            orderline.save()
            orderheader.save()
        messages.success(request, 'Order saved')
    else:
        messages.error(request, 'Order save error, please check fields below')
else:
    form = OrderHeaderForm(instance=orderid)
    formset = OrderLineFormSet(instance=orderid)
暂无标签

1 个回答

1

使用JavaScript来实时计算并显示那个字段的总值。

在你的视图中,不应该去查询获取创建的 OrderHeaderOrderLines,因为 form.save() 会返回这个实例。

做:

OrderHeader = form.save()
OrderLines  = formset.save()

我更喜欢

for orderline in orderlines:  
            orderline.orderline_total_price = orderline.linetotalprice()
            orderheader.orderheader_total_price += orderline.orderline_total_price // avoid recalculating, use that value calculated just before
            orderline.save()
            //orderheader.save() avoid saving each time for this model
 orderheader.save() // saving one time :)

你还可以把 linetotalprice 函数改成直接返回:

def linetotalprice(self):
    return self.orderline_product_price * self.orderline_quantity

并把 orderline_total_price 的默认值设为0。

撰写回答