Невозможно перебрать ManyToMany - как рассчитать сумму? - PullRequest
0 голосов
/ 30 сентября 2011

Мои модели выглядят так:

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 ]

4 голосов
/ 30 сентября 2011

Я бы заменил ваше общее поле на свойство:

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

причина в том, что когда вы добавляете элементы в коллекцию, ваш объект больше не сохраняется, поэтому он не обновляет ваш счетчик. С этим свойством вы всегда будете иметь правильные данные.

1 голос
/ 30 сентября 2011

Если вам действительно нужно это сделать, вы можете сначала сохранить экземпляр, если у него нет 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)
0 голосов
/ 30 сентября 2011

Использовать агрегацию.Заменить

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

на

from django.db.models import Sum

#..............
self.total = self.articles.aggregate(Sum('price'))['price__sum']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...