SQL-Äquivalent "LIKE" in der Django-Abfrage

108

Was entspricht dieser SQL-Anweisung in Django?

SELECT * FROM table_name WHERE string LIKE pattern;

Wie implementiere ich das in Django? Ich habe es versucht

result = table.objects.filter( pattern in string )

Das hat aber nicht funktioniert. Wie implementiere ich das?

Aswin Murugesh
quelle

Antworten:

200

Verwenden Sie __containsoder __icontains(ohne Berücksichtigung der Groß- und Kleinschreibung):

result = table.objects.filter(string__contains='pattern')

Das SQL-Äquivalent ist

SELECT ... WHERE string LIKE '%pattern%';
falsetru
quelle
22
Und für die Suche ohne Berücksichtigung der Groß- und Kleinschreibung verwenden Sie __icontains ->result = table.objects.filter(string__icontains='pattern')
Hitesh Garg
13
Diese Antwort deckt nur eine Teilmenge der möglichen Muster ab. Es würde nicht mit einem Muster wie umgehen %a%b%.
Kasperd
@kasperd, versuchen Sie:result = table.objects.filter(string__contains='a').filter(string__contains='b')
LS
1
@ LS Das würde passen bawas LIKE %a%b%nicht.
Kasperd
2
Diese Antwort ist aus den oben genannten Gründen unvollständig. Es sollte auch die Informationen in der Antwort von @ Dmitry enthalten.
Medley56
34

enthält und icontains von falsetru erwähnt machen fragen wie SELECT ... WHERE headline LIKE '%pattern%

Zusammen mit ihnen benötigen Sie möglicherweise solche mit ähnlichem Verhalten: Start mit , Start mit , Ende mit , Ende mit

Herstellung

SELECT ... WHERE headline LIKE 'pattern%

oder

SELECT ... WHERE headline LIKE '%pattern

Dmitriy Kuznetsov
quelle
9
result = table.objects.filter(string__icontains='pattern')

Suche ohne Berücksichtigung der Groß- und Kleinschreibung nach Zeichenfolge in einem Feld.

Venkat Kotra
quelle
2
Schön, aber die gleiche Antwort war bereits fast drei Jahre zuvor gegeben worden.
LS
3

Um die Reihenfolge der Wörter wie in der SQL-Anweisung LIKE '% pattern%' beizubehalten, verwende ich iregex, zum Beispiel:

qs = table.objects.filter(string__iregex=pattern.replace(' ', '.*'))

Zeichenfolgenmethoden sind unveränderlich, sodass sich Ihre Mustervariable nicht ändert und mit. * Sie nach 0 oder mehr Vorkommen eines Zeichens suchen, aber Linien brechen.

Verwenden Sie Folgendes, um die Musterwörter zu durchlaufen:

qs = table.objects
for word in pattern.split(' '):
    qs = qs.filter(string__icontains=word)

Die Reihenfolge der Wörter in Ihrem Muster bleibt nicht erhalten, für einige Leute, die funktionieren könnten, aber im Fall des Versuchs, die SQL-ähnliche Anweisung nachzuahmen, verwende ich die erste Option.

Rodrigo Ávila
quelle
2

Dies kann mit Djangos benutzerdefinierten Lookups erfolgen . Ich habe die Suche zu einer Django-ähnlichen Suchanwendung gemacht . Nachdem sie die Installation __likeLookup mit dem %und _Platzhalter aktiviert.

Der gesamte erforderliche Code in der Anwendung lautet:

from django.db.models import Lookup
from django.db.models.fields import Field


@Field.register_lookup
class Like(Lookup):
    lookup_name = 'like'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return '%s LIKE %s' % (lhs, rhs), params
Petr Dlouhý
quelle