无法迭代ManyToMany - 如何计算总和?

时间:2011-09-30 12:37:39

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

我的模特看起来像这样:

class Article(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()
price = models.FloatField()

def __unicode__(self):
    return "%s - %s" % (self.name, self.price)

class Order(models.Model):
client = models.ForeignKey(User)
articles = models.ManyToManyField(Article)
total = models.FloatField(editable=False, blank=True, default=0)

def __unicode__(self):
    return "%s - %s" % (self.client.username, self.total)

def save(self):
    for a in self.articles:
        self.total += a.price
    super(Order, self).save()

我尝试用save()计算总价。如果我尝试通过管理员保存订单,我会

  

'Order'实例需要具有主键值才能使用多对多关系

如果我打电话

super(Order, self).save()

在计算总和之前,我得到了

  

'ManyRelatedManager'对象不可迭代   

我不知道要做...我想在视图中计算总​​数,但我想将它存储在我的数据库中。

如何迭代Order-Model中的所有文章?

提前致谢:)

3 个答案:

答案 0 :(得分:4)

我用一个属性替换你的总字段:

class Order():
    ....
    @property
    def total(self):
        return self.articles.aggregate(Sum('price'))['price__sum']

原因是:当您向集合中添加项目时,您的对象不会再次保存,因此它不会更新您的计数器。使用此属性,您将确保始终拥有正确的数据。

答案 1 :(得分:1)

如果你真的需要这样做,你可以先保存实例,如果它没有PK:

def save(self, *args, **kwargs):
    if self.pk is None:
        super(Order, self).save(*args, **kwargs)
    for a in self.articles.all():
        self.total += a.price
    super(Order, self).save(*args, **kwargs)

答案 2 :(得分:0)

使用聚合。取代

for a in self.articles:
    self.total += a.price

from django.db.models import Sum

#..............
self.total = self.articles.aggregate(Sum('price'))['price__sum']