我有类发票,它(简化)具有以下属性:
class Invoice(models.Model)
number = models.CharField(verbose_name="Number", max_length=16)
issue_date = models.DateTimeField(verbose_name="Issue date", default=datetime.now)
total = models.FloatField(verbose_name="Total", blank=True, null=True)
然后,我有类 InvoiceLine,它表示发票可以包含的一行/几行:
class InvoiceLine(models.Model):
invoice = models.ForeignKey(Invoice, verbose_name="Invoice")
description = models.CharField(verbose_name="Description", max_length=64)
line_total = models.FloatField(verbose_name="Line total")
InvoiceLine 是 Invoice 的内联,我想要实现的是,当在管理员中有人保存发票及其行(一个或多个)时,计算发票总额。我试图通过覆盖方法保存来做到这一点:
class Invoice(models.Model)
number = models.CharField(verbose_name="Number", max_length=16)
issue_date = models.DateTimeField(verbose_name="Issue date", default=datetime.now)
total = models.FloatField(verbose_name="Total", blank=True, null=True)
def save(self, *args, **kwargs):
invoice_lines = InvoiceLine.objects.filter(invoice=self.id)
self.total = 0
for line in invoice_lines:
self.total=self.total+line.line_total
super(Invoice, self).save(*args, **kwargs)
问题是,当我在 InvoiceLine 中添加元素时,第一次保存并调用函数时,内联(InvoiceLine)中的新元素尚未存储,因此当我执行
InvoiceLine.objects.filter(invoice=self.id)
时,它们没有被考虑在内.因此,唯一有效的方法是节省两次。我也试过:
def save(self, *args, **kwargs):
super(Invoice, self).save(*args, **kwargs)
invoice_lines = InvoiceLine.objects.filter(invoice=self.pk)
self.total = 0
for line in invoice_lines:
self.total=self.total+line.line_total
super(Invoice, self).save(*args, **kwargs)
但有相同的结果。任何想法?
提前致谢!
最佳答案
最后我在 Change object after saving all inlines in Django Admin 的帖子上找到了它,它对我帮助很大。关键是在 admin.py 中,我已经有了我的类 InvoiceHeaderAdmin(admin.ModelAdmin)
,但是我不得不放置三个函数,以便在保存所有内联后修改 total 属性:这样,查询 invoice_lines = InvoiceLine.objects.filter(invoice_header=obj.pk)
不能正常工作以前,现在它完美无缺。周二功能 InvoiceHeaderAdmin 已如下:
class InvoiceHeaderAdmin(admin.ModelAdmin):
inlines = [InvoiceLineInline]
list_filter = ('format_line','issue_date',)
list_display = ('number','organization','issue_date','total',)
fields = ('format_line','organization','issue_date',)
#the following functions are for calculating the total price of the invoice header based on the lines
def response_add(self, request, new_object):
obj = self.after_saving_model_and_related_inlines(new_object)
return super(InvoiceHeaderAdmin, self).response_add(request, obj)
def response_change(self, request, obj):
obj = self.after_saving_model_and_related_inlines(obj)
return super(InvoiceHeaderAdmin, self).response_change(request, obj)
def after_saving_model_and_related_inlines(self, obj):
invoice_lines = InvoiceLine.objects.filter(invoice_header=obj.pk)
obj.total = 0
for line in invoice_lines:
obj.total=obj.total+line.line_total
obj.save()
return obj
线索是最后一个函数,其中所有内联都已保存,现在我可以从对象(发票)计算属性并修改它。