2013-11-24 6 views
8

मैं एक मॉडल है कहते हैं: last_list = ['Williams', 'Williamson']। तो अगर मैं हर किसी जिसका पहला नाम first_list में था चयन करने के लिए चाहता था मैं चला सकते हैं:Django एकाधिक स्तंभों के लिए मानों की "tuples" पर क्वेरीसमूह को फ़िल्टर

Person.objects.filter(firstname__in=first_list) 

और अगर मैं हर किसी जिसका अंतिम नाम last_list में था चयन करने के लिए चाहता था, मैं कर सकता:

Person.objects.filter(lastname__in=last_list) 

तो बहुत, बहुत अच्छा है। मैं एक ही समय में उन प्रतिबंधों के दोनों को चलाने के लिए चाहते हैं, इतना ही आसान है ...

Person.objects.filter(firstname__in=first_list, lastname__in=last_list) 

अगर मैं बजाय and शैली खोज के or शैली खोज करना चाहता था, मुझे लगता है कि Q वस्तुओं के साथ कर सकते हैं:

Person.objects.filter(Q(firstname__in=first_list) | Q(lastname__in=last_name)) 

लेकिन मेरे मन में जो कुछ है, वह थोड़ा और सूक्ष्म है। क्या होगा यदि मैं सिर्फ एक क्वेरीसेट वापस करना चाहता हूं जो पहले और अंतिम नामों के विशिष्ट संयोजनों को लौटाता है? अर्थात। मैं Person ऑब्जेक्ट्स लौटना चाहता हूं जिसके लिए (Person.firstname, Person.lastname)zip(first_names, last_names) में है। अर्थात। मैं बॉब विलियम्स या रॉब विलियमसन नामक किसी भी व्यक्ति को वापस लेना चाहता हूं (लेकिन बॉब विलियमसन या रॉब विलियम्स नामक किसी भी व्यक्ति को नहीं)।

मेरे वास्तविक उपयोग मामले में, first_list और last_list दोनों में ~ 100 तत्व होंगे।

फिलहाल, मुझे Django ऐप में इस समस्या को हल करने की आवश्यकता है। लेकिन मैं इसे अधिक सामान्य SQL संदर्भ में संभालने का सबसे अच्छा तरीका भी उत्सुक हूं।

धन्यवाद! (और मुझे पता है मैं कुछ भी स्पष्ट कर सकते हैं, तो बताएं।)

उत्तर

9

मैं एक बड़ी या खंड के अलावा बहुत समाधान नहीं दिख रहा है:

import operator 
from itertools import izip 
query = reduce(
    operator.or_, 
    (Q(firstname=fn, lastname=ln) for fn, ln in izip(first_list, last_list)) 
    ) 

Person.objects.filter(query) 
+0

मुझे एहसास नहीं हुआ कि आप प्रोग्रामिंग रूप से 'क्यू' कथन को गठबंधन कर सकते हैं! यह सही लगता है। क्या आप जानते हैं कि एसक्यूएल बिंदु से, इस प्रकार की क्वेरी कुशल है या नहीं? – 8one6

+0

जेनरेट किया गया एसक्यूएल वही होगा जैसा आप हाथ से लिखेंगे: 'चुनें से जहां (fistname = "X1" और lastname = "y1") या (firstname = "x2" और अंतिम नाम = "वाई 2") या '। अधिक दक्षता के लिए आप वास्तविक जीवन डेटा वाले बड़े डेटासेट पर (प्रथम नाम, अंतिम नाम) पर एक इंडेक्स जोड़ना चाह सकते हैं, यह _should_ चीजों को तेज़ करने के लिए पर्याप्त भेदभाव कर रहा है (मान लें कि आपका डीबी सर्वर इसका उपयोग करने के लिए पर्याप्त स्मार्ट है), लेकिन पहले इसे आज़माएं और जांचें कि क्या इसे वास्तव में किसी भी अनुकूलन की आवश्यकता है या नहीं। –

+0

ओह और यदि आप एक ही परिणाम प्राप्त करने के लिए एक SQL क्वेरी लिखने के किसी अन्य तरीके से जानते हैं तो कृपया मुझे बताएं, मैं हमेशा नई चीजें सीखने के लिए तैयार हूं। –

2

ब्रूनो के जवाब में काम करता है, लेकिन यह मेरे लिए गंदा महसूस करता है - दोनों पायथन स्तर पर और एसक्यूएल स्तर पर (ओआरएस का एक बड़ा संयोजन)। MySQL में कम से कम, आप निम्न SQL सिंटैक्स का उपयोग कर सकते हैं:

SELECT id FROM table WHERE (first_name, last_name) IN 
     (('John','Doe'),('Jane','Smith'),('Bill','Clinton')) 

Django के ORM यह करने के लिए एक सीधा रास्ता प्रदान नहीं करता है, तो मैं कच्चे एसक्यूएल का उपयोग करें: एक

User.objects.raw('SELECT * FROM table WHERE (first_name, last_name) IN %s', 
     [ (('John','Doe'),('Jane','Smith'),('Bill','Clinton')) ]) 

(यह वह जगह है एक तत्व के साथ सूची, क्वेरी में एकल% s से मेल खाते हैं। तत्व tuples का एक पुनरावृत्त है, इसलिए% s को tuples की SQL सूची में परिवर्तित कर दिया जाएगा)।

नोट्स:

  1. जैसा कि मैंने कहा, यह MySQL के लिए काम करता है। मुझे यकीन नहीं है कि अन्य बैकएंड इस वाक्यविन्यास का समर्थन करते हैं।
  2. इस व्यवहार से संबंधित पायथन-माइस्क्ल में एक बग, नवंबर 2013/MySQLdb 1.2.4 में तय किया गया था, इसलिए सुनिश्चित करें कि आपके पायथन MySQLdb पुस्तकालय उससे पुराने नहीं हैं।
संबंधित मुद्दे