无法遍历ManyToMany - 如何计算总和?
我的模型看起来是这样的:
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']
原因是:当你往集合里添加项目时,你的对象不会重新保存,所以总数不会更新。用这个属性的话,你就能确保总是有正确的数据。