2010-04-19 18 views
23

मेरे पास नामों की एक सूची है कि मैं केस असंवेदनशील मिलान करना चाहता हूं, क्या नीचे की तरह लूप का उपयोग किए बिना ऐसा करने का कोई तरीका है?Django क्वेरी केस-असंवेदनशील सूची मैच

a = ['name1', 'name2', 'name3'] 
result = any([Name.objects.filter(name__iexact=name) for name in a]) 

उत्तर

27

दुर्भाग्यवश, वहाँ कोई__iin क्षेत्र देखने हैं।

result = Name.objects.filter(name__iregex=r'(name1|name2|name3)') 

या यहाँ तक कि:

a = ['name1', 'name2', 'name3'] 
result = Name.objects.filter(name__iregex=r'(' + '|'.join(a) + ')') 

ध्यान दें कि यदि एक अक्षर हैं जो एक regex में विशेष कर रहे हैं शामिल कर सकते हैं, तो आप उन्हें ठीक से escape करने की जरूरत है लेकिन वहाँ एक iregex कि, उपयोगी हो सकता है तो तरह है ।

समाचार: Djano में 1.7 अपने स्वयं के लुकअप बनाना संभव है, इसलिए आप वास्तव में उचित शुरुआत के बाद filter(name__iin=['name1', 'name2', 'name3']) का उपयोग कर सकते हैं। विवरण के लिए https://docs.djangoproject.com/en/1.7/ref/models/lookups/ देखें।

+2

Postgres का उपयोग करने, केस-संवेदी अनुक्रमित समर्थन करता है, तो यह है कि मामले के लिए यह एक iregex मिलान की तुलना में प्रत्येक आइटम के लिए अलग "iexact" क्वेरी को चलाने के लिए तेजी से हो सकता है। Django के पोस्टग्रेज़ बैकएंड में "iexact" खोज एक UPPER() ट्रांसफॉर्म का उपयोग करती है, इसलिए उस पंक्ति के लिए UPPER() पर एक कस्टम इंडेक्स के साथ एक गति प्राप्त करना संभव है। – Evgeny

+5

मेरी इच्छा है कि वे __iin – JREAM

+0

@Evgeny को लागू करें, यदि आप कोई जवाब जोड़ सकते हैं, या हमें एक लिंक दे सकते हैं। धन्यवाद! –

3

पर क्या Rasmuj कहा जोड़ना, जैसे इतना

import re 
result = Name.objects.filter(name__iregex=r'(' + '|'.join([re.escape(n) for n in a]) + ')') 
3

ध्यान रखें कम से कम MySQL में आप वास्तव में उन्हें केस संवेदी बनाने के लिए अपने तालिकाओं में utf8_bin मिलान सेट करने के लिए है कि किसी भी उपयोगकर्ता के इनपुट से बचने। अन्यथा वे मामले संरक्षण कर रहे हैं लेकिन मामले असंवेदनशील हैं। जैसे

>>> models.Person.objects.filter(first__in=['John', 'Ringo']) 
[<Person: John Lennon>, <Person: Ringo Starr>] 
>>> models.Person.objects.filter(first__in=['joHn', 'RiNgO']) 
[<Person: John Lennon>, <Person: Ringo Starr>] 

तो, आप इस मुद्दे को पूरी तरह अनदेखा करने के लिए चुन सकते हैं यदि पोर्टेबिलिटी महत्वपूर्ण नहीं है और आप MySQL का उपयोग करें।

15

Postgresql में आप को यहां बताए गए एक केस संवेदी सूचकांक बनाने की कोशिश कर सकते:

https://stackoverflow.com/a/4124225/110274

फिर एक क्वेरी चलाने:

from django.db.models import Q 
name_filter = Q() 
for name in names: 
    name_filter |= Q(name__iexact=name) 
result = Name.objects.filter(name_filter) 

सूचकांक खोज तेजी से रेगुलर एक्सप्रेशन मिलान क्वेरी से चलेंगे।

+0

धन्यवाद! विचार मिला। –

+1

इस कोड के साथ देखें! यदि परिवर्तनीय नाम खाली हैं तो .filter उस मॉडल की सभी वस्तुओं को वापस कर देगा! – Benjamin

1

एक और तरीका है इस django query functions और एनोटेशन

from django.db.models.functions import Lower 
Record.objects.annotate(name_lower=Lower('name')).filter(name_lower__in=['two', 'one'] 
संबंधित मुद्दे