sql "LIKE" equivalente en la consulta de django

108

¿Cuál es el equivalente de esta declaración SQL en django?

SELECT * FROM table_name WHERE string LIKE pattern;

¿Cómo implemento esto en django? Lo intenté

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

Pero eso no funcionó. ¿Cómo implemento esto?

Aswin Murugesh
fuente

Respuestas:

200

Utilice __containso __icontains(no distingue entre mayúsculas y minúsculas):

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

El equivalente de SQL es

SELECT ... WHERE string LIKE '%pattern%';
falsetru
fuente
22
Y para la búsqueda que no distingue entre mayúsculas y minúsculas, use __icontains ->result = table.objects.filter(string__icontains='pattern')
Hitesh Garg
13
Esta respuesta solo cubre un subconjunto de los posibles patrones. No manejaría un patrón como %a%b%.
kasperd
@kasperd, prueba:result = table.objects.filter(string__contains='a').filter(string__contains='b')
LS
1
@LS Eso coincidiría con balo LIKE %a%b%que no.
kasperd
2
Esta respuesta está incompleta por las razones expuestas anteriormente. También debe incluir la información en la respuesta de @ Dmitry.
medley56
34

contiene y los icontains mencionados por falsetru hacen consultas como SELECT ... WHERE headline LIKE '%pattern%

Junto con ellos, es posible que necesite estos con un comportamiento similar: startswith , istartswith , endswith , iendswith

haciendo

SELECT ... WHERE headline LIKE 'pattern%

o

SELECT ... WHERE headline LIKE '%pattern

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

Búsqueda que no distingue entre mayúsculas y minúsculas de una cadena en un campo.

Venkat Kotra
fuente
2
Bien, pero la misma respuesta ya se había dado casi tres años antes.
LS
3

Para preservar el orden de las palabras como en la declaración sql LIKE '% pattern%' utilizo iregex, por ejemplo:

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

Los métodos de cadena son inmutables, por lo que su variable de patrón no cambiará y con. * buscará 0 o más apariciones de cualquier carácter excepto líneas de corte.

Usando lo siguiente para iterar sobre las palabras del patrón:

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

el orden de las palabras en su patrón no se conservará, para algunas personas eso podría funcionar, pero en el caso de intentar imitar la instrucción sql like, usaré la primera opción.

Rodrigo Ávila
fuente
2

Esto se puede hacer con las búsquedas personalizadas de Django . He realizado la búsqueda en una aplicación de búsqueda similar a Django . Después de instalarlo, la __likebúsqueda con %y_ , se habilitará comodines .

Todo el código necesario en la aplicación es:

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