Django

2009-05-19 24 views
24

में कस्टम ऑर्डरिंग आप Django QuerySet एस में एक विशिष्ट ऑर्डरिंग कैसे परिभाषित करते हैं?Django

विशेष रूप से, यदि मेरे पास QuerySet है तो: ['a10', 'a1', 'a2']

नियमित आदेश (Whatever.objects.order_by('someField') का उपयोग करके) मुझे ['a1', 'a10', 'a2'] देगा, जबकि मैं देख रहा हूं: ['a1', 'a2', 'a10']

अपनी खुद की ऑर्डर तकनीक को परिभाषित करने का सही तरीका क्या है?

उत्तर

39

जहां तक ​​मुझे पता है, इस तरह से डेटाबेस-साइड ऑर्डरिंग निर्दिष्ट करने का कोई तरीका नहीं है क्योंकि यह बहुत बैकएंड-विशिष्ट होगा। आप पुराने जमाने अजगर छंटाई का सहारा लेना चाह सकते हैं:

class Foo(models.Model): 
    name = models.CharField(max_length=128) 

Foo.objects.create(name='a10') 
Foo.objects.create(name='a1') 
Foo.objects.create(name='a2') 

ordered = sorted(Foo.objects.all(), key=lambda n: (n[0], int(n[1:]))) 
print ordered # yields a1, a2, 10 

आप अपने आप को मिल जाए एक बहुत छँटाई इस तरह की ज़रूरत है, मैं अपने मॉडल है कि आदेश प्रदर्शन के लिए एक कस्टम models.Manager उपवर्ग बनाने की सलाह देते हैं। कुछ ऐसा:

class FooManager(models.Manager): 
    def in_a_number_order(self, *args, **kwargs): 
     qs = self.get_query_set().filter(*args, **kwargs) 
     return sorted(qs, key=lambda n: (n[0], int(n[1:]))) 

class Foo(models.Model): 
    ... as before ... 
    objects = FooManager() 

print Foo.objects.in_a_number_order() 
print Foo.objects.in_a_number_order(id__in=[5, 4, 3]) # or any filtering expression 
+0

स्पॉट! अद्भुत जवाब, धन्यवाद! –

+2

मुझे इस विधि को आजमाते समय यह त्रुटि मिलती है: \t 'मॉडल' ऑब्जेक्ट अविभाज्य है – ninja123

+0

क्या 'सॉर्टेड' एक क्वेरीसेट लौटाता है? यह देखते हुए कि यह एक क्वेरीसेट पास कर चुका है, मुझे ऐसा लगता है, लेकिन मुझे लगता है कि इसे एक सूची में परिवर्तित किया जा सकता है या आंतरिक रूप से सॉर्ट करने के लिए कुछ भी हो सकता है, फिर * वह * वापस आ जाता है। –

0

यह इस बात पर निर्भर करता है कि आप इसका उपयोग कहां करना चाहते हैं।

यदि आप इसे अपने स्वयं के टेम्पलेट्स में उपयोग करना चाहते हैं, तो मैं एक टेम्पलेट टैग लिखने का सुझाव दूंगा, जो आपके लिए ऑर्डर करेगा इसमें, आप किसी भी सॉर्टिंग एल्गोरिदम का उपयोग कर सकते हैं जिसका आप उपयोग करना चाहते हैं।

व्यवस्थापक में मुझे अपने आवश्यकताओं के टेम्पलेट्स का विस्तार और के रूप में

25

ऊपर वर्णित @ Jarret के जवाब (पायथन में तरह करते हैं) एक टेम्पलेट टैग लोड करके छँटाई करते साधारण मामलों के लिए महान काम करता है। जैसे ही आपके पास एक बड़ी टेबल हो और कहें, केवल एक निश्चित तरीके से क्रमबद्ध परिणामों के पहले पृष्ठ को खींचें, यह दृष्टिकोण टूट जाता है (आपको सॉर्ट करने से पहले डेटाबेस से प्रत्येक पंक्ति को खींचना होगा)। उस समय मैं एक डिमॉर्मलाइज्ड "सॉर्ट" फ़ील्ड जोड़ना चाहता हूं जिसे आप "नाम" फ़ील्ड से सेव-टाइम पर पॉप्युलेट करते हैं, जिसे आप सामान्य तरीके से डीबी-स्तर पर सॉर्ट कर सकते हैं।

+2

+1; वास्तव में, आपका सुझाव वह है जिसे हमने अपने कुछ डेटा पर उपयोग किया है जिसका प्रयोग डीबी-अज्ञेय वातावरण में रिपोर्ट के लिए किया जाता है, और हमारे पास लाखों पंक्तियां हैं, इसलिए मैं यह कह सकता हूं कि यह अच्छी तरह से काम करता है । –

0

आप बड़े डेटा सेट है और इसके अलावा एक SOLR बैकएंड (Haystack साथ उदा) का उपयोग करते हैं: प्रकार क्षेत्रों के लिए प्रकार के रूप में numeric=true विकल्प के साथ

उपयोग solr.ICUCollationField। यह भाषा के अनुसार क्रमबद्ध होगा और यदि संख्याएं मौजूद हैं तो संख्या क्रम को स्ट्रिंग सॉर्टिंग के बजाय संख्यात्मक नियमों के अनुसार क्रमबद्ध करेंगी।

देखें: पर https://cwiki.apache.org/confluence/display/solr/Language+Analysis#LanguageAnalysis-UnicodeCollation http://www.solr-start.com/javadoc/solr-lucene/org/apache/solr/schema/ICUCollationField.html