无法遍历ManyToMany - 如何计算总和?

0 投票
3 回答
1190 浏览
提问于 2025-04-17 03:25

我的模型看起来是这样的:

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()

我试着在保存的时候计算总价格。如果我通过管理员界面保存一个订单,我会收到这个错误:

‘订单’实例在使用多对多关系之前需要有一个主键值。

如果我在计算总和之前调用:

super(Order, self).save()

我会得到这个错误:

‘ManyRelatedManager’对象不可迭代。

我不知道该怎么办……我想过在视图中计算总价,但我希望把它存储在我的数据库里。

我该如何遍历订单模型中的所有商品呢?

提前谢谢你们 :)

3 个回答

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']
1

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

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)
4

我建议把你的总数字段换成一个属性:

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

原因是:当你往集合里添加项目时,你的对象不会重新保存,所以总数不会更新。用这个属性的话,你就能确保总是有正确的数据。

撰写回答