tutorial site para framework fra espaƱol python django django-models

python - site - Filtre la base de datos Django para el campo que contiene cualquier valor en una matriz



framework django para python (3)

Tengo un modelo django y un campo que representa el nombre completo de un usuario. Mi cliente quiere que configure un filtro para buscar un usuario en función de una serie de cadenas en las que todas tienen que ser sensibles a mayúsculas y minúsculas dentro del nombre completo.

Por ejemplo

Si un usuario 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 tamaño dinámico, por lo que no sé cómo hacerlo.

¿Alguien tiene alguna idea?


Aún más corto usando las funciones de operator and_ o or_ para combinar la lista de condiciones Q()

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

Elementos que coinciden con todas las cadenas ( and_ )

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

Elementos que coinciden con cualquiera de las cadenas ( or_ )

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

La función Q() implementa __or__() y __and__() y __and__() para unir dos objetos Q() , de modo que se pueden llamar usando las funciones del operator correspondientes.


Haz sucesivas llamadas para filter , así:

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

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

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

Una forma más críptica de escribir esto, evitando el bucle explícito:

import operator # ... condition = reduce(operator.and_, [Q(full_name__icontains=s) for s in strings]) queryset = Profile.objects.filter(condition)


algo en este sentido:

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

EDIT: esto es incorrecto, el OP quiere nombres que contengan todas las cadenas simultáneamente.