sql „LIKE” odpowiednik w zapytaniu django

109

Jaki jest odpowiednik tej instrukcji SQL w django?

SELECT * FROM table_name WHERE string LIKE pattern;

Jak zaimplementować to w django? próbowałem

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

Ale to nie zadziałało. Jak to zaimplementować?

Aswin Murugesh
źródło

Odpowiedzi:

201

Użyj __containslub __icontains(bez rozróżniania wielkości liter):

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

Odpowiednik SQL to

SELECT ... WHERE string LIKE '%pattern%';
falsetru
źródło
22
A do wyszukiwania bez rozróżniania wielkości liter użyj __icontains ->result = table.objects.filter(string__icontains='pattern')
Hitesh Garg
13
Ta odpowiedź obejmuje tylko podzbiór możliwych wzorców. Nie poradziłby sobie z takim wzorem %a%b%.
kasperd
@kasperd, spróbuj:result = table.objects.filter(string__contains='a').filter(string__contains='b')
LS
1
@LS To pasuje, baktóre LIKE %a%b%nie.
kasperd
2
Ta odpowiedź jest niekompletna z powodów podanych powyżej. Powinien również zawierać informacje w odpowiedzi @ Dmitry.
medley56
34

zawiera i icontains wymienione przez falsetru tworzą zapytania takie jak SELECT ... WHERE headline LIKE '%pattern%

Wraz z nimi możesz potrzebować tych o podobnym zachowaniu: zaczyna się z , jest z , kończy z , z przyjaciółmi

zrobienie

SELECT ... WHERE headline LIKE 'pattern%

lub

SELECT ... WHERE headline LIKE '%pattern

Dmitriy Kuznetsov
źródło
9
result = table.objects.filter(string__icontains='pattern')

Wyszukiwanie ciągów znaków w polu bez rozróżniania wielkości liter.

Venkat Kotra
źródło
2
Niezła, ale ta sama odpowiedź została udzielona prawie trzy lata wcześniej.
LS
3

Aby zachować kolejność słów jak w instrukcji sql LIKE '% pattern%' używam iregex, na przykład:

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

metody łańcuchowe są niezmienne, więc zmienna wzorca nie zmieni się, a za pomocą. * będziesz szukał 0 lub więcej wystąpień dowolnego znaku oprócz linii przerwania.

Używając poniższego do iteracji po słowach wzorca:

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

kolejność słów w twoim wzorcu nie zostanie zachowana, dla niektórych osób może to zadziałać, ale w przypadku próby naśladowania instrukcji sql like użyję pierwszej opcji.

Rodrigo Ávila
źródło
2

Można to zrobić za pomocą niestandardowych wyszukiwań Django . Dokonałem wyszukiwania w aplikacji podobnej do Django . Po zainstalowaniu, __likewyszukiwanie z symbolami wieloznacznymi %i _będzie włączone.

Cały niezbędny kod w aplikacji to:

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ý
źródło