My models look like this:
class Article(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()
price = models.FloatField()
def __unicode__(self):
return "%s - %s" % (sel开发者_JS百科f.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()
And I try to calculate the total price in save(). If I try to save an order via the admin, I get
'Order' instance needs to have a primary key value before a many-to-many relationship can be used
If I call
super(Order, self).save()
before calculating the sum, I get
'ManyRelatedManager' object is not iterable .
I don't know to do... I thought about calculating total in the view, but I would like to store it in my database.
How to I iterate over all the articles in the Order-Model?
Thanks in advance :)
I'd replace your total field with a property:
class Order():
....
@property
def total(self):
return self.articles.aggregate(Sum('price'))['price__sum']
the reason is: when you add items to collection your object is not saved again, so it wouldn't update your counter. With this property you'll be sure to always have correct data.
If you really need to do this, you could save the instance first if it has no 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)
Use aggregation. Replace
for a in self.articles:
self.total += a.price
with
from django.db.models import Sum
#..............
self.total = self.articles.aggregate(Sum('price'))['price__sum']
精彩评论