Пост сохранение процесса с использованием ManyToMany с моделью посредника в админ - PullRequest
0 голосов
/ 29 ноября 2011

У меня есть модельное отношение, как определено в примерах из документации Django о связях ManyToMany с промежуточной моделью.

Я знаю, как это обычно работает, но это небольшое небольшое приложение, которое использует только DjangoАдмин, и это вызывает небольшой удар на дороге.

Вот что у меня есть:

class Item(models.Model):
    name = models.CharField(blank=True, max_length=100)
    vat_deductable = models.BooleanField(default=True)
    price = models.DecimalField(max_digits=12, decimal_places=2)

    def __unicode__(self):
        return self.name


class Invoice(models.Model):
    customer = models.ForeignKey(Relation)
    date = models.DateField(default=datetime.datetime.today)
    amount = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
    vat_amount = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
    is_paid = models.BooleanField(default=False)
    paid_on = models.DateField(blank=True, null=True)
    items = models.ManyToManyField(Item, through='SoldItem')

    def __unicode__(self):
        return unicode(self.customer) + u'_' + unicode(self.date)

class SoldItem(models.Model):
    item = models.ForeignKey(Item)
    invoice = models.ForeignKey(Invoice)
    qty = models.IntegerField(default=1, null=True)

Вот что я хотел бы сделать:

В конце концовмодели были сохранены (новый экземпляр родительской модели, любые новые экземпляры связанных моделей и любые новые экземпляры промежуточных моделей). Я хотел бы перебрать все экземпляры Item, связанные с вновь сохраненным счетом, чтобы я могдобавьте их цену и, возможно, НДС в два поля Invoice.amount и Invoice.vat_amount

Как бы я это сделал?Я пробовал использовать пользовательские методы сохранения как для модели Invoice, так и для ее формы ModelAdmin, но ни одно из этих мест не дает полной картины, когда формируются новые отношения.

Может быть, сигнал?Но что?

РЕДАКТИРОВАТЬ: я пробовал это решение: https://stackoverflow.com/a/2109177/150033

Было бы логично, что save_m2m будет гарантировать, что все будет сохранено, но кажется, что новейшие отношения всегда отсутствуют, когдапытаясь это.

1 Ответ

0 голосов
/ 29 ноября 2011

Хорошо, после долгих исследований я нашел кого-то еще, кто решил это http://igorsobreira.com/blog/2011/2/12/change-object-after-saving-all-inlines-in-django-admin/

В счете администратора:

class InvoiceAdmin(admin.ModelAdmin):
    inlines = [
        SoldItemAdmin,
    ]

    def response_add(self, request, new_object):
        obj = self.after_saving_model_and_related_inlines(new_object)
        return super(InvoiceAdmin, self).response_add(request, obj)

    def response_change(self, request, obj):
        obj = self.after_saving_model_and_related_inlines(obj)
        return super(InvoiceAdmin, self).response_change(request, obj)

    def after_saving_model_and_related_inlines(self, obj):
        solditem_changed.send(obj)
        return obj

И наш сигнал:

solditem_changed = Signal()
@receiver(solditem_changed)
def update_invoice(sender, **kwargs):
    if hasattr(sender, 'solditem_set'):
        total = 0
        for item in sender.solditem_set.all():
            total += item.item.price * item.qty
        sender.amount = total
        sender.save()
    else:
        sender.amount = 0
        sender.save()
...