¿Cuál es el equivalente SQL ”LIKE” en las consultas Django ORM?

4 minutos de lectura

Avatar de usuario de Aswin Mu ru gesh
aswin mu ru gesh

¿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?

avatar de usuario de falsetru
falsedad

Usar __contains o __icontains (sin distinción entre mayúsculas y minúsculas):

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

El equivalente de SQL es

SELECT ... WHERE string LIKE '%pattern%';

La respuesta de @Dmitri a continuación cubre patrones como ‘patrón%’ o ‘%patrón’

  • Y para el uso de búsqueda que no distingue entre mayúsculas y minúsculas __contiene -> result = table.objects.filter(string__icontains='pattern')

    –Hitesh Garg

    11 de agosto de 2015 a las 15:56


  • Esta respuesta solo cubre un subconjunto de los posibles patrones. No manejaría un patrón como %a%b%.

    – Kasperd

    18 de abril de 2016 a las 14:39

  • @kasperd, prueba: result = table.objects.filter(string__contains='a').filter(string__contains='b')

    – Sr. Lance E Sloan

    22 de marzo de 2019 a las 13:58


  • @LS Eso coincidiría ba cual LIKE %a%b% no lo haría

    – Kasperd

    22 de marzo de 2019 a las 22:14

  • Esta respuesta está incompleta por las razones expuestas anteriormente. También debe incluir la información en la respuesta de @Dmitry.

    – popurrí56

    15 de agosto de 2019 a las 16:39

Avatar de usuario de Dmitriy Kuznetsov
Dmitri Kuznetsov

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

Junto con ellos, es posible que necesite estos con un comportamiento similar:
comienza con, empiezo con, termina con, termina con

haciendo

SELECT ... WHERE headline LIKE 'pattern%

o

SELECT ... WHERE headline LIKE '%pattern

Esto se puede hacer con Búsquedas personalizadas de Django. He hecho la búsqueda en un Aplicación de búsqueda similar a Django. Después de instalarlo el __like buscar con el % y _ se habilitarán los 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

  • Esta es la respuesta adecuada a la pregunta, a diferencia de la respuesta aceptada.

    – Lutz Prechelt

    13 oct 2020 a las 11:59

  • Esto es genial, pero ¿existe algún riesgo de que el usuario pueda pasar datos sucios a la consulta?

    – wihlke

    4 de febrero de 2022 a las 21:02

result = table.objects.filter(string__icontains="pattern")

Búsqueda insensible a mayúsculas y minúsculas para cadena en un campo.

Para preservar el orden de las palabras como en la instrucción sql LIKE ‘%pattern%’, uso 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 ocurrencias de cualquier carácter excepto líneas de ruptura.

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 declaración sql like, usaré la primera opción.

  • Es posible que desee hacer el reemplazo .*? para tener una coincidencia perezosa y no consumir toda la cadena.

    – wihlke

    5 de febrero de 2022 a las 12:47

Avatar de usuario de Omer Anisfeld
Ömer Anisfeld

ejemplo completo: digamos que tenemos una tabla llamada DjangTable con nombre de campo de cadena file_name y queremos crear un filtro Django equivalente a la consulta que coincide con el espacio en la cadena file_name en mysql:

SELECT * FROM DjangTable WHERE file_name LIKE '% %' 
class DjangTable(UTModel):


    ...
    file_name = models.CharField(max_length=255, null=False)
    ...

en Django usando python será:

pattern = ' ' # same as mysql LIKE '% %'
DjangTable.objects.filter(file_name__contains=pattern)

  • Es posible que desee hacer el reemplazo .*? para tener una coincidencia perezosa y no consumir toda la cadena.

    – wihlke

    5 de febrero de 2022 a las 12:47

¿Ha sido útil esta solución?