如何在models.py中的save方法中获取内联对象

bca*_*cap 2 django django-models django-admin django-modeladmin django-admin-actions

我有类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)
Run Code Online (Sandbox Code Playgroud)

然后,我有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")
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

问题是,当我在InvoiceLine中添加元素时,第一次保存并调用functionsave时,内联(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)
Run Code Online (Sandbox Code Playgroud)

但结果相同.任何的想法?提前致谢!

bca*_*cap 6

最后,我在Django Admin保存所有内容后,在一个更改后的对象上找到了它,这对我帮助很大.关键是在admin.py中我已经拥有了我的类InvoiceHeaderAdmin(admin.ModelAdmin),但是我必须放置三个函数才能在保存所有内联后修改total属性:这样,invoice_lines = InvoiceLine.objects.filter(invoice_header=obj.pk)之前运行不正常的查询,现在它完美无缺.Tue函数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
Run Code Online (Sandbox Code Playgroud)

线索是最后一个功能,其中所有内联都已保存,现在我可以从对象(发票)计算属性并进行修改.