2010-04-19 11 views

Odpowiedz

27

Unfortunatley istnieją nie__iin pola odnośnika. Ale jest iregex, które mogą być przydatne, tak:

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

lub nawet:

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

Zauważ, że jeśli może zawierać znaki, które są wyjątkowe w regex, trzeba escape je prawidłowo .

AKTUALNOŚCI: W Djano 1.7 można tworzyć własne odnośniki, dzięki czemu można właściwie używać filter(name__iin=['name1', 'name2', 'name3']) po odpowiednim zainicjowaniu. Aby uzyskać szczegółowe informacje, patrz https://docs.djangoproject.com/en/1.7/ref/models/lookups/.

+2

PostgreSQL obsługuje indeksy case-niewrażliwe, więc w tym przypadku może być szybciej uruchomić osobny „iexact” zapytań dla każdej pozycji niż w iregex meczu. W postpresowym backendu "idriact" postu django używa transformacji UPPER(), więc z indeksem niestandardowym na UPPER() dla tego wiersza można uzyskać przyspieszenie. – Evgeny

+5

Szkoda, że ​​nie zaimplementują __iin – JREAM

+0

@Eggeny, jeśli chcesz dodać odpowiedź, lub podaj nam link. Dzięki! –

3

Dodanie na co Rasmuj powiedział uciec żadnego wejściowe użytkownika, jak tak

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

Należy pamiętać, że przynajmniej w MySQL trzeba ustawić utf8_bin sortowanie w tabelach faktycznie ich wielkość liter. W przeciwnym razie zachowują skrzynkę, ale nie uwzględniają wielkości liter. Na przykład.

>>> 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>] 

Tak więc, jeśli przenośność nie jest kluczowa i używasz MySQL, możesz całkowicie zignorować problem.

15

w PostgreSQL można spróbować tworzenia przypadek indeksowy niewrażliwe jak opisano tutaj:

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

Następnie uruchom kwerendę:

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) 

wyszukiwanie Index będzie działał szybciej niż zapytania dopasowania regex.

+0

Dzięki! wpadł na pomysł. –

+1

Uważaj na ten kod! Jeśli nazwy zmiennych są puste, to .filtr zwróci wszystkie obiekty tego modelu! – Benjamin

1

Inny sposób to użycie django query functions i adnotacji

from django.db.models.functions import Lower 
Record.objects.annotate(name_lower=Lower('name')).filter(name_lower__in=['two', 'one'] 
Powiązane problemy