J'ai un modèle
class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....
J'ai essayé ceci pour calculer la somme de price
dans cet ensemble de requêtes:
items = ItemPrice.objects.all().annotate(Sum('price'))
quel est le problème dans cette requête? ou y a-t-il un autre moyen de calculer la somme de la price
colonne?
Je sais que cela peut être fait en utilisant la boucle for sur le jeu de requêtes, mais j'ai besoin d'une solution élégante.
Merci!
Réponses:
Vous recherchez probablement
aggregate
from django.db.models import Sum ItemPrice.objects.aggregate(Sum('price')) # returns {'price__sum': 1000} for example
la source
{'price__sum':1000}
. Peut obtenir un flottant / un entier avecyourdict['price__sum']
Annoter ajoute un champ aux résultats:
>> Order.objects.annotate(total_price=Sum('price')) <QuerySet [<Order: L-555>, <Order: L-222>]> >> orders.first().total_price Decimal('340.00')
Aggregate renvoie un dict avec le résultat demandé:
>> Order.objects.aggregate(total_price=Sum('price')) {'total_price': Decimal('1260.00')}
la source
key
dans lequel stocker la sommevalue
.Utilisez
.aggregate(Sum('column'))['column__sum']
reefer mon exemple ci-dessoussum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
la source
En utilisant le profileur cProfile , je trouve que dans mon environnement de développement, il est plus efficace (plus rapide) de faire la somme des valeurs d'une liste que d'agréger en utilisant
Sum()
. par exemple: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.
J'ai testé cela dans différents contextes et il semble que l'utilisation
aggregate
prenne toujours plus de temps pour produire le même résultat. Bien que je soupçonne qu'il pourrait y avoir des avantages en termes de mémoire à l'utiliser au lieu de résumer une liste.la source
sum_a = sum(item.column for item in queryset)
. La seule différence est que l'[]
art. Cela économise de l'espace mémoire pour le calcul de la liste entière avant de l'sum()
itérer.