对子对象执行总计算的最简单方法是什么?

时间:2009-06-10 10:03:31

标签: django django-admin django-forms

我需要对Invoice模型对象执行一系列简单计算,该对象有许多与其关联的Order子项,其中包含订单数量和订单值等。这些都通过Invoice的管理表单进行管理(带有按顺序排列)

我正在使用的代码现在执行这样的计算:

发票(models.py)

def save():
    #get the total of all associated orders
    for order in self.invoice_orders.all():
    self.invoice_net_total += order.order_value
    super(Invoice, self).save()

在更改子订单数量然后保存表单时会导致一些问题 - 只有当我再次保存时,我才会获得以前的总数而不是新的总数。也许是由于Django保存父对象和子对象的方式?

我玩弄的其他选项是将此计算移动到子订单对象(准备可怕的代码):

订单(models.py)

def save():
  if not self.id:
    self.invoice.invoice_net_total += self.order_value
  elif self.id:
    #grab old instance
    old = Order.objects.get(pk=self.id)
    #remove that old total
    self.invoice.invoice_net_total -= old.order_value
    self.invoice.save()
    #add new total
    self.invoice.invoice_net_value += self.order_value
    self.invoice.save()

虽然那也不是很有效。

想知道是否有人可以指导我以直截了当的方式确保这些计算表现得如此?想到信号(对我而言比较新),但想知道这是否有点过分。我可能会过度思考这个!

谢谢

2 个答案:

答案 0 :(得分:4)

根据不同的想法,考虑甚至不明确保存发票总额。相反,每次查询发票时都可以动态重新计算。

我认为这是更好的建模,因为它可以避免冗余且可能不一致的数据。 SQL和Django足够智能,可以在每次需要时计算发票总额而无需太多开销。 ESP。如果您使用aggregation function

,则不会在程序中进行求和

答案 1 :(得分:0)

我认为您需要在进行计算之前显式保存子对象,因为您的查询引用了数据库中的对象,而表单中任何更改的对象可能都没有保存过。