我有以下模型:
class InvoiceEntry(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='entries', verbose_name=_("Invoice"))
line = models.CharField(max_length=500, verbose_name=_("Print Line"))
text = models.TextField(null=True, blank=True, verbose_name=_("Print Text"))
amount = models.PositiveIntegerField(verbose_name=_("Amount"))
unit_price = models.FloatField(null=True, blank=True, verbose_name=_("Unit Price"))
content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT, null=True, blank=True, validators=[validate_invoice_target_models])
object_id = models.PositiveIntegerField(null=True, blank=True)
is_separator = models.BooleanField(default=False)
我想获取一张发票的总和,因此我得到了一个使用invoice_entries = InvoiceEntry.objects.filter(invoice_id=2227)
的查询集,如果我应用values('amount', 'unit_price')
,则会得到:
{'amount': 0, 'unit_price': None}
{'amount': 4, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 1, 'unit_price': 11.5}
{'amount': 4, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 1, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 1, 'unit_price': 26.0}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 2, 'unit_price': 11.5}
{'amount': 9, 'unit_price': 23.0}
这总计为 716.00 ,但是当我尝试汇总时:
total = InvoiceEntry.objects.filter(invoice_id=2227).aggregate(amount=Sum('amount', field=('amount * unit_price')))
我得到:
{'amount': 52}
我不知道我在做什么错。
答案 0 :(得分:0)
Django中的F对象允许您进行额外的计算。 F对象生成SQL表达式,这些表达式描述数据库级别的操作。
尝试此操作,它应该正确计算总数。假设您使用的是Django 1.8 +
from django.db.models import Sum, F
InvoiceEntry.objects.filter(invoice_id=2227).aggregate(total=Sum(F('amount') * F('unit_price'))
有关Django中F表达式的更多信息: https://docs.djangoproject.com/en/2.2/ref/models/expressions/#f-expressions
答案 1 :(得分:0)
如果要基于发票进行汇总,则需要使用注释。汇总将处理模型中存在的所有发票。就像下面这样,在sql语言中没有分组依据。
select sum(column1 * column2) from table;
注释与分组依据有关。
select invoice, sum(column1 * column2) from table group by invoice;
在查询集下面可以解决您的问题。
from your_app import models
from django.db.models import F, Sum, FloatField
m = models.InvoiceEntry.objects.values('invoice').annotate(sum=Sum(F('amount') * F('unit_price'), output_field=FloatField()))
<QuerySet [{'invoice': 1, 'sum': 48.0}, {'invoice': 2, 'sum': 8.0}]>
这将提供所有发票的金额。如果需要特定发票,可以使用过滤器。
m = models.InvoiceEntry.objects.filter(invoice=1).values('invoice').annotate(sum=Sum(F('amount')
* F('unit_price'), output_field=FloatField()))
<QuerySet [{'invoice': 1, 'sum': 48.0}]>