मैं दो Django क्वेरी का मिलन कैसे कर सकता हूं?


94

मुझे दो कस्टम प्रबंधक विधियों के साथ एक Django मॉडल मिला है। प्रत्येक वस्तु के एक अलग गुण के आधार पर मॉडल की वस्तुओं का एक अलग सबसेट देता है।

क्या क्वेरीसेट या वस्तुओं की सूची प्राप्त करने का कोई तरीका है, जो प्रत्येक प्रबंधक विधि द्वारा लौटाए गए क्वेरीसेट का संघ है?


3
(हटाए गए उत्तर से) इस प्रश्न को एक भिन्नता के लिए देखें जो अलग-अलग मॉडलों से क्वेरीस के साथ काम करता है: stackoverflow.com/questions/431628/…
rnevius

1
संस्करण 1.11 से शुरू होकर, django क्वेरी सेट में एक अंतर्निहित संघ विधि है। मैंने इसे भविष्य के संदर्भ के लिए एक उत्तर के रूप में जोड़ा है
जोस चेरियन

जवाबों:


181

यह काम करता है और थोड़ा साफ दिखता है:

records = query1 | query2

यदि आप डुप्लिकेट नहीं चाहते हैं, तो आपको संलग्न करना होगा .distinct():

records = (query1 | query2).distinct()

6
जबकि स्वीकृत उत्तर एक संघ पुनरावृत्ति देता है (सटीक होने के लिए सूची), जैसे ओपी ने पूछा है, यह विधि क्वेरी का एक वास्तविक संघ लौटाती है। इस क्वेरी को आगे भी संचालित किया जा सकता है, जो कई परिस्थितियों में वांछित है।
क्रिस्टियन साइबुलस्की

5
एक Django बग के कारण, यह निर्माण कभी-कभी गलत परिणाम दे सकता है जब एस के साथ काम करता है ManyToManyField। उदाहरण के लिए, आप कभी-कभी देखेंगे कि records.count()इससे अधिक होगा query1.count() + query2.count(), जो स्पष्ट रूप से गलत है।
जियान

4
@ जियान आप बग के साथ django संस्करण और djangoproject मुद्दे की एक कड़ी को स्पष्ट कर सकते हैं?
IMFletcher

10
रिकॉर्ड = क्वेरी 1 | क्वेरी 2; रिकॉर्ड्स = record.distinct () मुझे सही परिणाम देगा
यूजीन

5
आप पायथन में ऑपरेटरों को ओवरलोड कर सकते हैं। Docs.python.org/2/library/operator.html देखें । तो Django क्या करता है QuerySet ऑब्जेक्ट के लिए विशेष तरीके बनाते हैं। कोड यहाँ देखें: github.com/django/django/blob/master/django/db/models/...QuerySet वर्ग के लिए तरीके प्रदान __and__और __or__है कि कहा जाता है जब &या |ऑपरेटरों दोनों के बीच उपयोग किया जाता है QuerySetवस्तुओं (भी के लिए इस्तेमाल Qके साथ-साथ वर्ग )।
जॉर्डन रीटर

50

संस्करण 1.11 से शुरू , django क्वेरी में एक बिल्टिन यूनियन विधि है।

q = q1.union(q2) #q will contain all unique records of q1 + q2
q = q1.union(q2, all=True) #q will contain all records of q1 + q2 including duplicates
q = q1.union(q2,q3) # more than 2 queryset union

अधिक उदाहरणों के लिए इस पर मेरा ब्लॉग पोस्ट देखें ।


मुझे काम पूरा नहीं हो सका। क्लाइंट को वापस करने से पहले मेरी क्वेरी को एक सेट पर डालना समाप्त कर दिया।
ब्रैडेन होल्ट

1
@ ब्रैडहॉल्ट, ऑल = ट्रू, इसका मतलब है कि इसमें डुप्लिकेट रिकॉर्ड होंगे। आप इसे सेट करने से बचने के लिए बस सभी = सही को निकाल सकते हैं।
जोस चेरियन

इस काम के बाद DjangoFilterBackend, मैं यूनियन और DjangoFilterBackend का उपयोग कैसे कर सकता हूं?
nesalexy

दुर्भाग्य से, यह मॉडल के मेटा में परिभाषित डिफ़ॉल्ट ऑर्डर के साथ मॉडल के लिए काम नहीं करता है। जब भी मैं इन्हें .union के साथ संयोजित करने का प्रयास करता हूं, मुझे निम्नलिखित त्रुटि प्राप्त होती है: "यौगिक कथनों के उपवर्ग में अनुमति नहीं है।"
jrial

4

मैं 'query1.union (query2)' का उपयोग करने के बजाय 'query1 | QUERY2 '; मुझे उपरोक्त दो तरीकों से अलग-अलग परिणाम मिले और पूर्व में वही हुआ जिसकी मुझे उम्मीद थी। निम्नलिखित है जो मैं भर आया था:

print "union result:"
for element in query_set1.union(query_set2):
    print element

print "| result:"
for element in (query_set1 | query_set2):
    print element

परिणाम:

union result:
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object

| result:
KafkaTopic object
KafkaTopic object

1
कृपया कोड पेस्ट करें, कोड की छवियां नहीं। छवियों में पाठ खोज योग्य नहीं है, आप सत्यापन के लिए इसे अपने संपादक में कॉपी / पेस्ट नहीं कर सकते हैं, और आवश्यकता से अधिक जगह ले सकते हैं। कोड के रूप में कोड को चिह्नित करने के लिए बैकटिक्स का उपयोग करें, ताकि यह सही ढंग से स्वरूपित हो जाए। पाठ प्रविष्टि बॉक्स के आगे "सहायता" लिंक देखें।
jrial

अपडेट करने के लिए धन्यवाद। :)
१४:०४ पर jrial
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.