如何计算多对多的产品总和

时间:2014-11-30 06:37:52

标签: django django-models many-to-many django-signals

我有这个代码,但他们不计算当前的amout。我需要保存2次才能完成工作。他们需要在桌子上约会。

菜单类有:

product
description
price

from django.db import models
from django.utils.encoding import smart_unicode
from menu.models import Menu

class Order(models.Model):
    date = models.DateTimeField(auto_now_add=True, null=True)
    table = models.IntegerField(null=False, max_length=2, )
    products = models.ManyToManyField(Menu,through='OrderProduct')
    paid = models.BooleanField(default=False)
    total = models.IntegerField(,default=0,editable=False,null=True)

    def save(self, *args, **kwargs):
        self.total = 0
        for product in self.products.all():
            relationship_queryset = OrderProduct.objects.filter(order=self, product=product)
            for p in relationship_queryset.all():
                 self.total +=  p.total_products
        super(Order, self).save(*args, **kwargs)

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

class OrderProduct(models.Model):
    order = models.ForeignKey(Order)
    product = models.ForeignKey(Menu)
    num_products = models.IntegerField(max_length=2)
    total_products = models.IntegerField(default=0,editable=False)

    def save(self, *args, **kwargs):
        self.total_products = (self.product.precio * self.num_products)
        super(OrderProduct, self).save(*args, **kwargs)

UPDATE2

我使用 post_save 但返回 超出最大递归深度
他们发现了 @cached_property 的提示,并将自定义seve方法更改为此缓存属性。我不知道是最好的方法,但是工作。

@cached_property
def total(self):
    x = 0
    for product in self.productos.all():
        relationship_queryset = OrderProduct.objects.filter(order=self, product=product)
        for p in relationship_queryset.all():
             x +=  p.total_products
    return x

1 个答案:

答案 0 :(得分:1)

使用聚合。您不必在模型中存储总价值。只需在每次需要时查询它。 https://docs.djangoproject.com/en/dev/topics/db/aggregation/

>>> OrderProduct.objects.filter(product=product).aggregate(
...    total=Sum(F('total_products'), output_field=IntegerField())
{'total': 123}

我没有测试过这段代码,但是你明白了。