¿Cómo usar “Y” en un filtro Django?

4 minutos de lectura

avatar de usuario de gath
gath

¿Cómo creo un filtro “Y” para recuperar objetos en Django? por ejemplo, me gustaría recuperar una fila que tenga una combinación de dos palabras en un solo campo.

Por ejemplo, la siguiente consulta SQL hace exactamente eso cuando la ejecuto en la base de datos mysql:

SELECT * FROM myapp_question
WHERE ((question LIKE '%software%') AND (question LIKE '%java%'))

¿Cómo logras esto en Django usando filtros?

Avatar de usuario de David Berger
david berger

En aras de la exhaustividad, mencionemos simplemente el Q método de objeto:

from django.db.models import Q
criterion1 = Q(question__contains="software")
criterion2 = Q(question__contains="java")
q = Question.objects.filter(criterion1 & criterion2)

Tenga en cuenta que las otras respuestas aquí son más simples y están mejor adaptadas para su caso de uso, pero si alguien con un problema similar pero un poco más complejo (como necesitar “no” o “o”) ve esto, es bueno tener la referencia aquí.

  • Solo quería mencionar que tu comentario de pasada me ayudó. ¡Gracias!

    – Alfonso

    1 de marzo de 2016 a las 17:20

  • Vea aqui para mas informacion: docs.djangoproject.com/en/3.1/topics/db/queries/…

    – el hombre de las preguntas

    14 de octubre de 2020 a las 1:09

Avatar de usuario de Andrea Di Persio
andrea di persio

(actualizar: esta respuesta ya no funcionará y dará el error de sintaxis keyword argument repeated)

mymodel.objects.filter(first_name__icontains="Foo", first_name__icontains="Bar")

actualizar: Mucho tiempo desde que escribí esta respuesta e hice algo de django, pero estoy seguro de que hasta el día de hoy el mejor enfoque es usar el método de objeto Q como muestra David Berger aquí: ¿Cómo uso AND en un filtro de Django?

  • Esto hace no trabaja para mí en Django 1.6 y Postgres. Obtengo un “SyntaxError: argumento de palabra clave repetido” cada vez que hay dos o más palabras clave iguales. Solo funciona la solución con Q de David Berger.

    – margusholland

    30 de mayo de 2014 a las 7:32

  • Tengo un país modelo con un campo de código de país corto (cc_short): >>> países = Country.objects.filter(cc_short__icontains=’A’, cc_short__icontains=’B’) Archivo ““, línea 1 SyntaxError: palabra clave argumento repetido

    – margusholland

    9 de julio de 2014 a las 8:56


  • Esto también no es trabajo para mí tampoco. Mismo error que @margusholland. Usando Django 1.7.5. Código en cuestión: talks = Talks.objects.filter(description__contains=topics,description__contains=terms).order_by('-datetime') Tanto los temas como los términos son listas.

    – Austin A.

    21/04/2015 a las 20:37

  • ¡Tenga en cuenta que ambos campos son iguales! Es Python en sí mismo el que no permite esto, no funcionará en CUALQUIER django/db. Esta no debería ser una respuesta aceptada.

    – rsalmei

    17 de enero de 2017 a las 16:25

  • Hola @MayankMehtani, debería funcionar si los argumentos de las palabras clave son diferentes, no solo sus valores.

    – rsalmei

    18 mayo 2020 a las 22:58

avatar de usuario de mipadi
mipadi

Puede encadenar expresiones de filtro en Django:

q = Question.objects.filter(question__contains="software").filter(question__contains="java")

Puede encontrar más información en los documentos de Django en “Filtros de encadenamiento“.

  • Esta respuesta puede darte resultados incorrectos dependiendo de tu escenario. Usando , in filter vs encadenamiento de filtros puede tener diferentes resultados. Lectura adicional: SO Respuesta y documentos oficiales

    – usuario

    08/07/2014 a las 19:16


  • esta NO es la respuesta a la pregunta formulada. Dará salida diferencial. Pero esto es lo que estaba buscando. Lo que OP quería, allobjects.filter(name=x o name=y) pero esta respuesta dará first = allobjects.filter(name=x) y luego filter first.filter(name=y). Espero que lo entiendan. Lo siento por el pseudocódigo.

    – mohammed_ayaz

    18 de abril de 2020 a las 18:44

  • @mohammed_ayaz La pregunta solicita una operación AND, no una operación OR.

    – mipadi

    19 abr 2020 a las 20:10

  • Tengo mucha curiosidad por qué esta respuesta fue incluso votada. Además de que tiene una lógica OR, tendrá resultados diferentes si los campos filtrados son de tablas referenciadas.

    – Alex MM

    6 de mayo de 2020 a las 9:24


  • @Alexandru-MihaiManolescu: ¿Qué tiene lógica OR? Esta pregunta es un Y, no un O.

    – mipadi

    7 mayo 2020 a las 16:50

Puedes usar AND con filtrar() usando & o q() y & Como se muestra abajo:

# "store/views.py"

from .models import Question
from django.db.models import Q
from django.http import HttpResponse

def test(request):

    # With "&"
                                                              # ↓ Here
    qs = Question.objects.filter(question__contains="software") & \ 
         Question.objects.filter(question__contains="java")
    print(qs)

    # With "Q()" and "&"
                               # ↓ Here                         # ↓ Here
    qs = Question.objects.filter(Q(question__contains="software") & 
                                 Q(question__contains="java"))
    print(qs)                  # ↑ Here

    return HttpResponse("Test")

¿Ha sido útil esta solución?