Tengo un modelo
class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....
Intenté esto para calcular la suma de price
en este conjunto de consultas:
items = ItemPrice.objects.all().annotate(Sum('price'))
¿Qué hay de malo en esta consulta? ¿O hay alguna otra forma de calcular la suma de la price
columna?
Sé que esto se puede hacer usando for loop en queryset pero necesito una solución elegante.
¡Gracias!
Respuestas:
Probablemente estas buscando
aggregate
from django.db.models import Sum ItemPrice.objects.aggregate(Sum('price')) # returns {'price__sum': 1000} for example
fuente
{'price__sum':1000}
. Puede obtener flotante / entero conyourdict['price__sum']
Anotar agrega un campo a los resultados:
>> Order.objects.annotate(total_price=Sum('price')) <QuerySet [<Order: L-555>, <Order: L-222>]> >> orders.first().total_price Decimal('340.00')
Agregado devuelve un dictado con el resultado solicitado:
>> Order.objects.aggregate(total_price=Sum('price')) {'total_price': Decimal('1260.00')}
fuente
key
para almacenar la sumavalue
.Use
.aggregate(Sum('column'))['column__sum']
reefer mi ejemplo a continuaciónsum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
fuente
Usando cProfile Profiler , encuentro que en mi entorno de desarrollo, es más eficiente (más rápido) sumar los valores de una lista que agregar usando
Sum()
. p.ej: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.
Probé esto en diferentes contextos y parece que usarlo
aggregate
siempre lleva más tiempo para producir el mismo resultado. Aunque sospecho que podría haber ventajas en cuanto a memoria para usarlo en lugar de sumar una lista.fuente
sum_a = sum(item.column for item in queryset)
. La única diferencia son los[]
s eliminados . Esto ahorra espacio en la memoria para calcular la lista completa antes desum()
iterar sobre ella.