2012-08-10 16 views
13

मान लें कि मेरे पास एक पोस्टकोड फ़ील्ड वाला पता मॉडल है। मैं पोस्टकोड इस लाइन के साथ "123" के साथ शुरू के साथ पतों देखने कर सकते हैं:डीजेगो फ़ील्ड पर शुरू होता है

Address.objects.filter(postcode__startswith="123") 

अब, मैं इस "दूसरी तरह के आसपास" खोज करने की जरूरत है। मेरे पास एक पोस्टकोड_prefix फ़ील्ड वाला पता मॉडल है, और मुझे उन सभी पतों को पुनर्प्राप्त करने की आवश्यकता है जिनके लिए postcode_prefix किसी दिए गए कोड का उपसर्ग है, जैसे कि "12345"। तो अगर मेरे डीबी में मेरे पास postcode_prefix = "123" और "234" के साथ 2 पते थे, तो केवल पहला ही वापस कर दिया जाएगा।

कुछ की तरह:

Address.objects.filter("12345".startswith(postcode_prefix)) 

समस्या यह है कि यह काम नहीं करता है। एकमात्र समाधान मैं के साथ आ सकते हैं, जैसे पहले चार पर एक फिल्टर प्रदर्शन करने के लिए है:

Address.objects.filter(postcode_prefix__startswith="12345"[0]) 

और फिर, जब मैं परिणाम प्राप्त, एक सूची समझ है कि उन्हें ठीक से फिल्टर, इस तरह करते हैं:

results = [r for r in results if "12345".startswith(r.postcode_prefix)] 

क्या डीजेंगो में ऐसा करने का कोई बेहतर तरीका है? , धन्यवाद फैब्रिजियो

+0

क्या उपसर्ग की लंबाई तय है या इसमें परिवर्तनीय लंबाई है? – cyroxx

+0

परिवर्तनीय लंबाई :) – sfabriz

उत्तर

8

एसक्यूएल संदर्भ में, क्या हासिल करना चाहते हैं की तरह पढ़ता है ()

SELECT * 
FROM address 
WHERE '12345' LIKE postcode_prefix||'%' 

यह वास्तव में एक मानक क्वेरी नहीं है और मैं किसी भी संभावना केवल प्राप्त (का उपयोग कर Django में इस लक्ष्य को हासिल करने के लिए नहीं दिख रहा है/फिल्टर(): '12345' पोस्टकोड आप खोज रहे हैं) है।

हालांकि, Django extra() के साथ अतिरिक्त एसक्यूएल खंड प्रदान करने के लिए एक तरीका प्रदान करता:

postcode = '12345' 
Address.objects.extra(where=["%s LIKE postcode_prefix||'%%'"], params=[postcode]) 

कृपया आगे के संदर्भ के लिए Django documentation on extra() देखते हैं। यह भी ध्यान रखें कि अतिरिक्त में शुद्ध SQL शामिल है, इसलिए आपको यह सुनिश्चित करना होगा कि क्लॉज आपके डेटाबेस के लिए मान्य है।

आशा है कि यह आपके लिए काम करता है।

+1

धन्यवाद। यह संभवत: ऐसा करने का सबसे अच्छा तरीका है, जैसा कि आप कहते हैं, यह डीबी निर्भर हो जाता है। मुझे खुशी है कि कोई त्वरित डीजेंगो जादू नहीं है जिसे मैं याद कर रहा था। बहुत बहुत धन्यवाद! फैब्रिजियो – sfabriz

11

मुझे लगता है कि आप लाइन ठीक से इस रूप में लिखा है अपने "की तरह कुछ" के साथ क्या करना कोशिश कर रहे हैं:

Address.objects.filter(postcode__startswith=postcode_prefix) 
+0

वास्तव में ओपी इसे दूसरे तरीके से चाहता है। – cyroxx

+0

बिल्कुल। मुझे दूसरी तरफ की जरूरत है। मैं इसे एक से अधिक तरीकों से पाइथन के साथ कर सकता हूं, लेकिन मुझे यह जानने की जरूरत है कि क्या मुझे ऐसा करने के लिए कुछ उचित django तरीका याद आ रहा है। :) – sfabriz

0

ए नहीं मुद्दा https://code.djangoproject.com/ticket/13363, आप यह कर सकता है:

queryset.extra(select={'myconst': "'this superstring is myconst value'"}).filter(myconst__contains=F('myfield')) 

हो सकता है, वे किसी समस्या को हल हो जाएगा और यह काम कर सकते हैं।

बी। यदि समस्या 16731 ​​नहीं है (माफ करना पूर्ण यूआरएल प्रदान नहीं करता है, पर्याप्त प्रतिनिधि नहीं है, ऊपर एक और टिकट देखें) तो आप कस्टम एग्रीग्रेशन फ़ंक्शन के निर्माण के साथ '.annotate' के साथ जोड़े गए फ़ील्ड द्वारा फ़िल्टर कर सकते हैं, जैसे: http://coder.cl/2011/09/custom-aggregates-on-django/

सी अंतिम और सफल।

  1. django.db.models.sql.Query.query_terms
  2. django.db.models.fields.Field: मैं निम्नलिखित के इस monkeypatching का उपयोग कर पाई हैं।get_prep_lookup
  3. django.db.models.fields.Field.get_db_prep_lookup
  4. django.db.models.sql.where.WhereNode.make_atom

जो रिवर्स है बस परिभाषित कस्टम देखने '_ प्रारंभ हो', ' _startswith'

0

का तर्क एक संभावित विकल्प।

q=reduce(lambda a,b:a|b, [Q(postcode__startswith=postcode[:i+1]) for i in range(len(postcode))])

इस प्रकार (पता नहीं है कि यह कैसे की तरह से पीछे नहीं परम के रूप में एक स्तंभ के साथ स्वीकार कर लिया समाधान की तुलना में, निष्पादन समय में है), तो आप सभी उपसर्गों उत्पन्न करना होगा और या उन्हें एक साथ ...

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