तालिका फ़ील्ड से अलग मानों का चयन करें


104

मैं Django के ORM के आसपास अपना सिर पाने के लिए संघर्ष कर रहा हूं। मैं जो करना चाहता हूं उसे मेरी मेज पर एक क्षेत्र के भीतर अलग-अलग मूल्यों की एक सूची मिलती है .... निम्नलिखित में से एक के बराबर:

SELECT DISTINCT myfieldname FROM mytable

(या वैकल्पिक रूप से)

SELECT myfieldname FROM mytable GROUP BY myfieldname

मैं कम से कम कच्चे sql का सहारा लेने से पहले Django रास्ता करना चाहते हैं। उदाहरण के लिए, एक तालिका के साथ:

आईडी, सड़क, शहर

1, मेन स्ट्रीट, हल

2, अन्य स्ट्रीट, हल

3, बाइबल वे, लीसेस्टर

4, एक और तरीका, लीसेस्टर

5, हाई स्ट्रीट, लोंडीडियम

मैं पाना चाहूंगा:

हल, लीसेस्टर, लोंडीडियम।

जवाबों:


202

कहो कि आपका मॉडल 'शॉप' है

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city')

चूँकि आपके पास Metaवर्ग orderingविशेषता सेट हो सकती है , आप उपयोग order_by()करते समय किसी भी क्रम को साफ़ करने के लिए मापदंडों के बिना उपयोग कर सकते हैं distinct()। के तहत प्रलेखन देखें order_by()

यदि आप किसी भी ऑर्डर को क्वेरी पर लागू नहीं करना चाहते हैं, तो डिफ़ॉल्ट ऑर्डर भी नहीं, ऑर्डर_बाय () बिना किसी पैरामीटर के।

और distinct()नोट में जहां यह distinct()ऑर्डर देने के साथ उपयोग करने के मुद्दों पर चर्चा करता है ।

अपने DB को क्वेरी करने के लिए, आपको बस कॉल करना होगा:

models.Shop.objects.order_by().values('city').distinct()

यह एक डिक्शनरी देता है

या

models.Shop.objects.order_by().values_list('city').distinct()

यह वह रिटर्न देता है ValuesListQuerySetजिसे आप किसी को दे सकते हैं list। आप परिणामों को समतल flat=Trueकरने के values_listलिए भी जोड़ सकते हैं ।

इसे भी देखें: क्षेत्र के अनुसार क्वेरीसेट के अलग-अलग मूल्य प्राप्त करें


29
वास्तव में वह काम करता है। तथापि! मैं इसे अपने सभी मॉडलों पर काम करने के लिए नहीं मिला। अजीब तरह से, यह कुछ पर काम किया, लेकिन दूसरों पर नहीं। उन लोगों के लिए जिनके पास मेटा ऑर्डर करने का काम नहीं करता है। इसलिए, आपको पहले क्वेरी पर ऑर्डर क्लियर करना होगा। model.Shop.objects.order_by ()। मान ('शहर') अलग। ()
अलज

2
यह नोट करना महत्वपूर्ण है कि values_listवास्तव में एक सूची वापस नहीं आती है। यह क्वेरीसेट की तरह कुछ देता है। मैंने मानों (सूची) के आसपास हमेशा सूची () का उपयोग करना उपयोगी पाया।
धीरोसोर

8
values_listValuesListQuerySet लौटाता है जो एक पुनरावृत्ति है। सूची में कास्टिंग करना आसान हो सकता है, लेकिन जब सभी पंक्तियों का मूल्यांकन एक ही बार में करना होता है, तो विशेष रूप से बड़े डेटा सेट के साथ प्रदर्शन को भी रद्द कर सकते हैं।
पीटर किल्कुक

3
Meta: ordering = ()Django ORM और की "सुविधा" objects.distinct()बनाम objects.ordering().distinct()हमें भ्रम के घंटे का कारण बना। उस उत्पाद पर एक उपभोक्ता-सुरक्षा चेतावनी स्टिकर होना चाहिए;) हम भविष्य में सिर को खरोंचने से रोकने के लिए एक नो-मेटा-ऑर्डरिंग-विशेषता नीति स्थापित कर सकते हैं।
हॉब्स

आप बिना मापदंडों के उपयोग के साथ Metaकक्षा को बंद कर सकते हैं orderingऔर मुद्दों को हल कर सकते हैं । यह QuerySet API डॉक्स में " यदि आप चाहते हैं कि कोई भी ऑर्डर क्वेरी पर लागू न हो, डिफ़ॉल्ट ऑर्डर भी नहीं हो, तो कोई पैरामीटर न होने के कारण कॉल करें "distinctorder_by()order_by()order_by()
Mark Mikofski

11

जुजुले के अभी भी बहुत प्रासंगिक उत्तर के अलावा , मुझे यह भी काफी महत्वपूर्ण लगता है कि प्रश्नों order_by()पर निहितार्थों के बारे में पता होना चाहिए distinct("field_name")हालाँकि, यह एक सुविधा केवल पोस्टग्रेज है!

यदि आप Postgres का उपयोग कर रहे हैं और यदि आप किसी फ़ील्ड नाम को परिभाषित करते हैं, जो क्वेरी के लिए अलग होना चाहिए, तो order_by()उसी क्रम में समान फ़ील्ड नाम (या फ़ील्ड नाम) के साथ प्रारंभ करने की आवश्यकता है (बाद में और फ़ील्ड हो सकते हैं)।

ध्यान दें

जब आप फ़ील्ड नाम निर्दिष्ट करते हैं, तो आपको QuerySet में एक order_by () प्रदान करना होगा, और क्रम_by () में फ़ील्ड को उसी क्रम में फ़ील्ड को विशिष्ट () से शुरू करना होगा।

उदाहरण के लिए, SELECT DISTINCT ON (a) आपको कॉलम a में प्रत्येक मान के लिए पहली पंक्ति देता है। यदि आप कोई आदेश निर्दिष्ट नहीं करते हैं, तो आपको कुछ मनमानी पंक्ति मिल जाएगी।

यदि आप उदाहरण के लिए उन शहरों की एक सूची निकालना चाहते हैं जिन्हें आप दुकानों के बारे में जानते हैं, तो जुगुले का उदाहरण इसके लिए अनुकूलित करना होगा:

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  

2

उदाहरण द्वारा:

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.