Tengo un modelo de django y un campo que representa a un usuario de nombre completo. Mi cliente quiere establecer un filtro para buscar un usuario basado en una matriz de cadenas, donde todos ellos tienen que ser sensibles a mayúsculas y minúsculas contenida en el nombre completo.

Por ejemplo

Si los usuarios full_name = "Keith, Thomson S."

Y tengo una lista ['keith','s','thomson']

Quiero realizar el filtro equivalente de

Profile.objects.filter(full_name__icontains='keith',full_name__icontains='s',full_name__icontains='thomson')

El problema es que esta lista puede ser de la dinámica de tamaño, así que no sé cómo hacerlo.

Alguien tiene alguna idea?

OriginalEl autor xizor | 2012-01-20

3 Comentarios

  1. 40

    Hacer llamadas sucesivas a filter, así:

    queryset = Profile.objects.all()
    strings = ['keith', 's', 'thompson']
    for string in strings:
        queryset = queryset.filter(full_name__icontains=string)

    Alternativamente, usted puede & juntos un montón de Q objetos:

    condition = Q(full_name__icontains=s[0])
    for string in strings[1:]:
        condition &= Q(full_name__icontains=string)
    queryset = Profile.objects.filter(condition) 

    Más críptico manera de escribir esto, evitando la explícita bucle:

    import operator
    # ...
    condition = reduce(operator.and_, [Q(full_name__icontains=s) for s in strings])
    queryset = Profile.objects.filter(condition)
    Me pregunto cuál es la final de la expresión sql se va a parecer después de que el encadenamiento de todos estos filtros.
    Acabo de probar (bueno, algo similar) — que se traduce a una serie de ANDs en el where cláusula, es decir, full_name LIKE %keith% AND full_name LIKE %s% AND ...
    tenga en cuenta que el operador predeterminado para múltiples objetos Q es Y por lo que sólo puede *[Q1, Q2, Q3] sin usar reducir / operador.and_.
    hace este trabajo sobre las claves principales. estoy teniendo problema similar, obj = ModelClass.objetos.filtro de(nombre de__contains(«substr»)) el nombre es una clave principal ?

    OriginalEl autor Ismail Badawi

  2. 8

    Aún más el uso de la operator funciones and_ o or_ combinar la lista de Q() condiciones

    from operator import and_, or_
    li = ['keith', 's', 'thompson']

    Los elementos que coinciden todas las cadenas (and_)

    Profile.objects.filter(reduce(and_, [Q(full_name__icontains=q) for q in li]))

    Los elementos que coinciden con alguna de las cadenas (or_)

    Profile.objects.filter(reduce(or_, [Q(full_name__icontains=q) for q in li]))

    La Q() función implementa __or__() y __and__() para unir dos Q() objetos juntos, por lo que puede ser llamado mediante el correspondiente operator funciones.

    OriginalEl autor C14L

  3. 2

    algo a lo largo de estas líneas:

    
    array = ['keith', 's', 'thomson']
    regex = '^.*(%s).*$' % '|'.join(array)
    Profile.objects.filter(full_name__iregex=regex)

    EDIT: esto está mal, el OP quiere nombres que contienen todas las cadenas simultáneamente.

    OriginalEl autor akonsu

Dejar respuesta

Please enter your comment!
Please enter your name here