Eu tenho uma modelo
class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....
Tentei calcular a soma de price
neste queryset:
items = ItemPrice.objects.all().annotate(Sum('price'))
o que há de errado nesta consulta? ou existe alguma outra maneira de calcular a soma da price
coluna?
Eu sei que isso pode ser feito usando o loop for no queryset, mas preciso de uma solução elegante.
Obrigado!
Respostas:
Você provavelmente está procurando por
aggregate
from django.db.models import Sum ItemPrice.objects.aggregate(Sum('price')) # returns {'price__sum': 1000} for example
fonte
{'price__sum':1000}
. Pode obter float / inteiro comyourdict['price__sum']
Annotate adiciona um campo aos resultados:
>> Order.objects.annotate(total_price=Sum('price')) <QuerySet [<Order: L-555>, <Order: L-222>]> >> orders.first().total_price Decimal('340.00')
O agregado retorna um dict com o resultado solicitado:
>> Order.objects.aggregate(total_price=Sum('price')) {'total_price': Decimal('1260.00')}
fonte
key
no qual armazenar a somavalue
.Use
.aggregate(Sum('column'))['column__sum']
reefer meu exemplo abaixosum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
fonte
Usando o criador de perfil cProfile , descobri que, em meu ambiente de desenvolvimento, é mais eficiente (mais rápido) somar os valores de uma lista do que agregar usando
Sum()
. por exemplo:sum_a = sum([item.column for item in queryset]) # Definitely takes more memory. sum_b = queryset.aggregate(Sum('column')).get('column__sum') # Takes about 20% more time.
Eu testei isso em diferentes contextos e parece que o uso
aggregate
leva sempre mais tempo para produzir o mesmo resultado. Embora eu suspeite que pode haver vantagens em termos de memória para usá-lo em vez de somar uma lista.fonte
sum_a = sum(item.column for item in queryset)
. A única diferença são os[]
s removidos . Isso economiza espaço de memória para calcular a lista inteira antes desum()
iterar sobre ela.