sql “LIKE” equivalente na consulta django

108

Qual é o equivalente a esta instrução SQL no django?

SELECT * FROM table_name WHERE string LIKE pattern;

Como faço para implementar isso no django? eu tentei

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

Mas isso não funcionou. Como faço para implementar isso?

Aswin Murugesh
fonte

Respostas:

200

Use __containsou __icontains(não diferencia maiúsculas de minúsculas):

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

O equivalente em SQL é

SELECT ... WHERE string LIKE '%pattern%';
falsetru
fonte
22
E para pesquisa que não diferencia maiúsculas de minúsculas, use __icontains ->result = table.objects.filter(string__icontains='pattern')
Hitesh Garg
13
Essa resposta cobre apenas um subconjunto dos padrões possíveis. Não iria lidar com um padrão como %a%b%.
Kasperd de
@kasperd, tente:result = table.objects.filter(string__contains='a').filter(string__contains='b')
LS
1
@LS Isso combinaria com o baque LIKE %a%b%não.
Kasperd
2
Esta resposta está incompleta pelas razões expostas acima. Também deve incluir as informações na resposta de @Dmitry.
medley56
34

contém e icontains mencionados por falsetru fazem consultas como SELECT ... WHERE headline LIKE '%pattern%

Junto com eles, você pode precisar daqueles com comportamento semelhante: startswith , istartswith , endswith , iendswith

fazer

SELECT ... WHERE headline LIKE 'pattern%

ou

SELECT ... WHERE headline LIKE '%pattern

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

Pesquisa sem distinção entre maiúsculas e minúsculas para string em um campo.

Venkat Kotra
fonte
2
Legal, mas a mesma resposta já havia sido dada quase três anos antes.
LS
3

Para preservar a ordem das palavras como na instrução sql LIKE '% pattern%', eu uso iregex, por exemplo:

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

os métodos de string são imutáveis, portanto, sua variável de padrão não será alterada e com. * você estará procurando 0 ou mais ocorrências de qualquer caractere, exceto linhas de quebra.

Usando o seguinte para iterar sobre as palavras padrão:

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

a ordem das palavras em seu padrão não será preservada, para algumas pessoas isso poderia funcionar, mas no caso de tentar imitar a instrução sql like usarei a primeira opção.

Rodrigo Ávila
fonte
2

Isso pode ser feito com as pesquisas personalizadas do Django . Eu fiz a pesquisa em um aplicativo de pesquisa semelhante ao Django . Após a instalação, a __likepesquisa com os curingas %e _será habilitada.

Todo o código necessário no aplicativo é:

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ý
fonte