2010-04-19 6 views

Antwort

27

Unfortunatley gibt es kein__iin Feld Lookup. Aber es gibt eine iregex die nützlich sein könnten, etwa so:

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

oder sogar:

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

Beachten Sie, dass, wenn ein Zeichen enthalten, die in einem regex speziell sind, müssen Sie sie richtig escape .

NEWS: In Djano 1.7 ist es möglich, eigene Lookups zu erstellen, so dass Sie nach korrekter Initialisierung tatsächlich filter(name__iin=['name1', 'name2', 'name3']) verwenden können. Einzelheiten finden Sie unter https://docs.djangoproject.com/en/1.7/ref/models/lookups/.

+2

Postgres unterstützt Groß- und Kleinschreibung Indizes, so für diesen Fall mit schneller sein kann separate „iexact“ Abfragen für jedes Element als ein iregex Spiel laufen zu lassen. In Djangos Postgres-Backend verwendet die "iexact" -Suche eine UPPER() -Transformation, also mit einem benutzerdefinierten Index auf UPPER() für diese Zeile ist es möglich, eine Beschleunigung zu erhalten. – Evgeny

+5

Ich wünschte, sie würden __iin – JREAM

+0

@Evgeny implementieren Ich wünschte, Sie könnten eine Antwort hinzufügen, oder geben Sie uns einen Link. Vielen Dank! –

3

Hinzufügen auf das Gesagte Rasmuj, entziehen sich jeglicher Benutzereingaben wie so

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

Beachten Sie, dass zumindest in MySQL Sie utf8_bin Sortierung in Tabellen setzen, um sie tatsächlich Groß- und Kleinschreibung zu machen. Ansonsten sind sie fallsicher, aber ohne Berücksichtigung der Groß- und Kleinschreibung. Z.B.

Wenn also die Portabilität nicht entscheidend ist und Sie MySQL verwenden, können Sie das Problem ganz ignorieren.

15

In Postgresql könnten Sie versuchen, ein Groß- und Kleinschreibung Index zu erstellen, wie hier beschrieben:

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

Dann eine Abfrage ausführen:

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) 

Indexsuche schneller laufen als die Regex Matching-Abfrage.

+0

Danke! habe die Idee. –

+1

Vorsicht mit diesem Code! Wenn der Variablenname leer ist, gibt der Filter alle Objekte dieses Modells zurück! – Benjamin

1

Eine weitere zu auf diese Weise django query functions und Annotation

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