Django: क्वेरी के माध्यम से स्तंभ मानों के योग की गणना करें


92

मेरे पास एक मॉडल है

class ItemPrice( models.Model ):
     price = models.DecimalField ( max_digits = 8, decimal_places=2 )
     ....

मैंने priceइस क्वेरी में राशि की गणना करने के लिए यह कोशिश की :

items = ItemPrice.objects.all().annotate(Sum('price'))

इस प्रश्न में क्या गलत है? या priceस्तंभ के योग की गणना करने का कोई अन्य तरीका है ?

मुझे पता है कि यह क्वेरीसेट पर लूप के लिए उपयोग करके किया जा सकता है, लेकिन मुझे एक सुरुचिपूर्ण समाधान की आवश्यकता है।

धन्यवाद!


क्या इससे आपके सवाल का जवाब मिलता है? Django सोम क्वेरी?
फ़्लिम

जवाबों:


196

आप शायद ढूंढ रहे हैं aggregate

from django.db.models import Sum

ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example

1
मैं कुल गणना कैसे प्राप्त कर सकता हूं जिसकी कीमत = 5000 है?
अनुज शर्मा

6
याद रखें रिटर्न शब्दकोश फ्लोट / पूर्णांक जैसे नहीं {'price__sum':1000}। के साथ फ्लोट / पूर्णांक प्राप्त कर सकते हैंyourdict['price__sum']
जोश

34

एनोटेट परिणामों में एक क्षेत्र जोड़ता है:

>> Order.objects.annotate(total_price=Sum('price'))
<QuerySet [<Order: L-555>, <Order: L-222>]>

>> orders.first().total_price
Decimal('340.00')

पूछा गया परिणाम के साथ एक अलग रिटर्न देता है:

>> Order.objects.aggregate(total_price=Sum('price'))
{'total_price': Decimal('1260.00')}

मैं आपको यह दिखाने के लिए सराहना करता हूं keyकि योग valueको कैसे स्टोर करना है।
मिकी

32

.aggregate(Sum('column'))['column__sum']नीचे मेरे उदाहरण का उपयोग करें

sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']

5

CProfile प्रोफाइलर का उपयोग करते हुए , मुझे लगता है कि मेरे विकास के माहौल में, सूची का उपयोग करने की तुलना में सूची के मूल्यों को योग करना अधिक कुशल (तेज) है Sum()। उदाहरण के लिए:

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.

मैंने अलग-अलग संदर्भों में इसका परीक्षण किया और ऐसा लगता है aggregateकि समान परिणाम का उपयोग करने में हमेशा अधिक समय लगता है। हालांकि मुझे संदेह है कि सूची का योग करने के बजाय इसका उपयोग करने के लिए फ़ायदेमंद मेमोरी-वार हो सकता है।


1
वैकल्पिक रूप से, एक सूची के बजाय एक जनरेटर अभिव्यक्ति का उपयोग करें sum_a = sum(item.column for item in queryset):। एकमात्र अंतर हटाए गए []एस है। यह पूरी सूची की गणना करने से पहले मेमोरी स्पेस को उस sum()पर पुनरावृत्त होने से बचाता है।
कोड-अपरेंटिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.