2009-08-04 10 views
16

मैं Django में एक मॉडल के कई क्षेत्रों में एक निश्चित स्ट्रिंग देखना चाहता हूँ। आदर्श रूप में, यह कुछ इसी प्रकार होगा:Django क्वेरी में गतिशील रूप से लुकअप फ़ील्ड नाम कैसे प्रदान करें?

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 
results = [] 
for field in fields: 
    lookup = "%s__contains" 
    results.append(Item.objects.filter(lookup=keyword)) 

बेशक यह काम नहीं करेगा, क्योंकि "लुकअप" को किसी क्षेत्र में हल नहीं किया जा सकता है। ऐसा करने के लिए कोई और रास्ता नहीं है?

+0

डुप्लिक लिंक के लिए धन्यवाद - मैं इसकी तलाश कर रहा था लेकिन इस में कीवर्ड के सही संयोजन को मारना मुश्किल है। –

उत्तर

15

मुझे लगता है कि Django क्वेरी सिस्टम के साथ ऐसा करने का एक बेहतर तरीका हो सकता है। यहां अपना रास्ता कैसे करें।

पायथन आपको शब्दकोशों को ** के साथ उपसर्ग करके तर्क सूची के रूप में उपयोग करने की अनुमति देता है।

lookup = "%s__contains" % field 
results.append(Item.objects.filter(**{ lookup: keyword})) 
+0

नीचे बोटोंडस का उत्तर देखें। यह Django क्वेरी सिस्टम के साथ समाधान है जिसे मैंने संदर्भित किया है, और उम्मीद है कि यह एसक्यूएल में निष्पादित होने के बाद से तेजी से चलना चाहिए। –

4

मैं DialZ का जवाब लेकिन प्रदर्शन के कारणों के लिए क्वेरी का निर्माण करना चाहिए और उसके बाद डेटाबेस मारा एक बार के बजाय में सभी परिणाम श्रृंखलाबद्ध चाहते: किस्मत की जगह के साथ, आप इस तरह कुछ करने के लिए सक्षम होना चाहिए एक सूची:

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 

# this makes an empty queryset object which we can 
# add to later using the | operator 
results = Item.objects.none() 

for field in fields: 
    lookup = "%s__contains" % field 
    query = {lookup : keyword} 
    results = results | Item.objects.filter(**query) 

मैं एक समय में इनमें से किसी एक किया havn't, लेकिन मैं कर रहा हूँ यकीन है कि Django वास्तव में इस कोड में बिल्कुल डेटाबेस हिट नहीं होंगे। जब आप रिकॉर्ड्स

23

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

from django.db.models import Q 

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 

Qr = None 
for field in fields: 
    q = Q(**{"%s__contains" % field: keyword }) 
    if Qr: 
     Qr = Qr | q # or & for filtering 
    else: 
     Qr = q 

# this you can now combine with other filters, exclude etc.  
results = MyModel.objects.filter(Qr) 
+1

यह एक बिल्कुल अद्भुत जवाब है। यह मेरा दिन भर में आया। क्या आपने इसे कहीं भी पोस्ट किया है? मुझे नहीं लगता कि ज्यादातर लोगों का एहसास है कि यह संभव है (क्यू ऑब्जेक्ट kwargs के एक धक्का को पॉप्युलेट करने के लिए फील्ड नामों पर लूपिंग)। – jMyles

+1

@jMyles: धन्यवाद, खुशी है कि मैं मदद कर सकता हूं। नहीं, मुझे नहीं लगता कि मैंने इसे कहीं और पोस्ट किया है। लेकिन सामान्य रूप से गतिशील तरीके से 'क्यू' वस्तुओं को संयोजित करने में, जटिल प्रश्नों को आसानी से बनाने के लिए एक बहुत ही शक्तिशाली विधि है। –

+0

मैंने अभी एक प्रश्न पोस्ट किया है जिसके लिए उत्तर समान हो सकता है - मैं लूप और क्यू और ऑपरेटर का उपयोग कर सकता हूं। यह यहां है: http://stackoverflow.com/questions/6783747/django-queryset-to-match-all-related-objects – jMyles

संबंधित मुद्दे