Question:
I'm using Django 1.7.8
I have models.py
class SaleDetail(models.Model):
quantity = models.PositiveSmallIntegerField(_('quantidade'))
price_sale = models.DecimalField(
def get_subtotal(self):
return self.price_sale * self.quantity
subtotal = property(get_subtotal)
./manage.py shell
>>> from vendas_project.vendas.models import SaleDetail
>>> from django.db.models import Sum, F, FloatField
>>> q = SaleDetail.objects.values('price_sale', 'quantity').filter(sale=1)
>>> q.aggregate(Sum(F('price_sale') * F('quantity')), output_field=FloatField())
Generates the error:
field_list = aggregate.lookup.split(LOOKUP_SEP)
AttributeError:
'ExpressionNode' object has no attribute 'split'
How do you calculate subtotals and total in Django?
I need the result, example:
price_sale quantity subtotal
10.50 2 21.00
9.55 3 28.65
total = 49.65
Answer:
In version 1.8 to generate the subtotal you must use annotate
and to generate the total you must use aggregate
.
It is necessary to use ExpressionWrapper when performing calculations with different types of values.
Example:
>>> from django.db.models import F, DecimalField, ExpressionWrapper
>>> q = SaleDetail.objects.filter(sale=1).values('price_sale', 'quantity')
>>> q_com_subtotal = q.annotate(subtotal=ExpressionWrapper(F('price_sale') * F('quantity')), output_field=DecimalField())
>>> q_com_subtotal[0].subtotal
21.0
>>> calculo_total = q_com_subtotal.aggregate(total=Sum('subtotal'))
>>> calculo_total.total
49.65
References:
- https://docs.djangoproject.com/en/1.8/ref/models/expressions/#query-expressions
- https://docs.djangoproject.com/en/1.8/ref/models/expressions/#django.db.models.ExpressionWrapper