Django में SELECT MAX कैसे करें?


91

मेरे पास वस्तुओं की एक सूची है कि मैं एक फ़ील्ड का अधिकतम मूल्य देने के लिए एक क्वेरी कैसे चला सकता हूं:

मैं इस कोड का उपयोग कर रहा हूं:

def get_best_argument(self):
    try:
        arg = self.argument_set.order_by('-rating')[0].details
    except IndexError:
        return 'no posts'
    return arg

रेटिंग एक पूर्णांक है

जवाबों:


173

देखें इस । आपका कोड कुछ इस तरह होगा:

from django.db.models import Max
# Generates a "SELECT MAX..." query
Argument.objects.aggregate(Max('rating')) # {'rating__max': 5}

आप मौजूदा क्वेरी पर भी इसका उपयोग कर सकते हैं:

from django.db.models import Max
args = Argument.objects.filter(name='foo') # or whatever arbitrary queryset
args.aggregate(Max('rating')) # {'rating__max': 5}

यदि आपको उस मॉडल उदाहरण की आवश्यकता है जिसमें यह अधिकतम मान है, तो आपके द्वारा पोस्ट किया गया कोड संभवतः इसे करने का सबसे अच्छा तरीका है:

arg = args.order_by('-rating')[0]

ध्यान दें कि यदि क्वेरी खाली है, तो यह त्रुटि करेगा, अर्थात यदि कोई तर्क क्वेरी से मेल नहीं खाता (क्योंकि [0]भाग बढ़ाएगा IndexError)। यदि आप उस व्यवहार से बचना चाहते हैं और इसके बजाय बस Noneउस स्थिति में वापस आते हैं , तो उपयोग करें .first():

arg = args.order_by('-rating').first() # may return None

4
मुझे एक्चुएल तर्क ऑब्जेक्ट की आवश्यकता है जिसमें वह मैक्स है, इसलिए मैं विवरण फ़ील्ड प्रिंट कर सकता हूं। Args.aggregate (अधिकतम ('रेटिंग') कॉल केवल उच्चतम रेटिंग देता है। मैं उच्चतम रेटिंग के साथ आर्ग की तलाश कर रहा हूं।
जोहड़

1
आपके बाहर निकलने के कोड में क्या गड़बड़ है - Argument.objects.order_by ("- रेटिंग") [0]?
एडमकेजी

74

Django में ' नवीनतम (field_name = कोई नहीं) ' फ़ंक्शन भी है जो नवीनतम (अधिकतम मान) प्रविष्टि पाता है। यह न केवल तारीख क्षेत्रों के साथ काम करता है, बल्कि तार और पूर्णांक के साथ भी काम करता है।

आप उस फ़ंक्शन को कॉल करते समय फ़ील्ड का नाम दे सकते हैं:

max_rated_entry = YourModel.objects.latest('rating')
return max_rated_entry.details

या आप पहले से ही अपने मॉडल मेटा डेटा में उस फ़ील्ड का नाम दे सकते हैं:

from django.db import models

class YourModel(models.Model):
    #your class definition
    class Meta:
        get_latest_by = 'rating'

अब आप बिना किसी पैरामीटर के 'नवीनतम' () कॉल कर सकते हैं:

max_rated_entry = YourModel.objects.latest()
return max_rated_entry.details

3
यह उपयोग करने का एक शानदार तरीका है latest()। यदि आपको न्यूनतम मूल्य के साथ रिकॉर्ड की आवश्यकता है, तो आप उपयोग कर सकते हैं earliest()
सैक्स

7
latest()और earliest()गैर-दिनांक फ़ील्ड के साथ भी काम करता है, लेकिन यह कार्यान्वयन का एक साइड-इफेक्ट है। आपको उपयोग करना चाहिए <your-queryset>.order_by('<interested-field>').first()या <your-queryset>.order_by('<interested-field>').last()यह सुनिश्चित करने के लिए कि आपका कोड अभी भी काम करेगा, भले ही Django डेवलपर्स बदल जाएगा latest()और earliest()कार्यान्वयन केवल दिनांक फ़ील्ड के साथ काम करने के लिए होगा ।
mrnfrancesco

यह एक बुरा जवाब है: 1) जैसा कि पहले ही देखा गया है कि यह पहले से लागू है और भविष्य में इसे बदला जा सकता है 2) यह बहुत पठनीय नहीं है - अधिकतम संख्या जरूरी नहीं कि एक को बचाया जाए (या किसी अन्य अर्थ में)
मिखाइल गेरेसिमोव

47

मैंने इसे अपनी परियोजना के लिए परीक्षण किया है, यह ओ / (एन) समय में अधिकतम / मिनट पाता है:

from django.db.models import Max

# Find the maximum value of the rating and then get the record with that rating. 
# Notice the double underscores in rating__max
max_rating = App.objects.aggregate(Max('rating'))['rating__max']
return App.objects.get(rating=max_rating)

यह आपको संपूर्ण तालिका को छांटने और शीर्ष (O (n * logn)) प्राप्त करने के बजाय, अधिकतम तत्वों में से एक को कुशलतापूर्वक प्राप्त करने की गारंटी है।


8
बिग-ओ कभी-कभी अभ्यास में सहन नहीं करता है, खासकर छोटे एन के लिए, जहां गुणांक और कार्यान्वयन मामला है। आपका कोड python / django में है, जो बाइटकोड में संकलित है और इसे अनुकूलित किया जा सकता है या नहीं। डेटाबेस को संभवतः एक भाषा में लिखा जाता है जिसे मशीन निर्देशों के लिए अनुकूलित और संकलित किया जाता है। इसके अलावा, डेटाबेस में सॉर्ट करने का कोई वास्तविक कारण नहीं है, अगर फ़ंक्शन केवल अधिकतम मान की तलाश में है। एक अंतर्निहित डेटाबेस फ़ंक्शन पर हैंड-बिल्ड कोड का उपयोग करने से पहले मैं समय पर डेटा देखना चाहता / चाहती हूं।
benevolentprof

5
@ हाफिम मुझे नहीं लगता कि आपके द्वारा पोस्ट किया गया कोड पूरी तरह से सही है। अगर आपको पता चला है कि आपके पास एक से अधिक अधिकतम हैं (मान लें कि आपके पास 5 सितारों के साथ दो ऐप्स हैं) तो "गेट" का उपयोग करके एक त्रुटि उत्पन्न होगी।
रायडेल मिरांडा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.