79 votes

Django : la requête utilisant contient chaque valeur dans une liste

Je dois effectuer une requête Django qui vérifie si un champ contient toutes les valeurs d'une liste. La liste sera de longueur variable

Exemple

 User.objects.filter(first_name__contains=['x','y','z'])

135voto

Ignacio Vazquez-Abrams Points 312628
import operator
from django.db.models import Q

User.objects.filter(reduce(operator.and_, (Q(first_name__contains=x) for x in ['x', 'y', 'z'])))

pour python 3

 from functools import reduce

.

39voto

user2872619 Points 301
import operator
from django.db.models import Q

q = ['x', 'y', 'z']
query = reduce(operator.and_, (Q(first_name__contains = item) for item in q))
result = User.objects.filter(query)

5voto

Mark Mishyn Points 912

Juste une autre approche.

 qs = User.objects.all()
for search_term in ('x', 'y', 'z'):
    qs = qs.filter(first_name__contains=search_term)

Je ne sais pas si c'est mieux, mais c'est plus lisible.

Remarque : les ensembles de requêtes sont paresseux, ce code crée donc une requête de 1 base de données.

1voto

Michel Dudouze Points 1
from django.db.models import Q
User.objects.filter(Q(first_name__contains=x)&Q(first_name__contains=y)&Q(first_name__contains=z))

Fonctionne pour moi sur Django 1.8 python 2.7

doc => https://docs.djangoproject.com/en/1.8/ref/models/querysets/#q-objects

pour les plus récents => https://docs.djangoproject.com/en/2.1/ref/models/querysets/#q-objects

1voto

AltoBalto Points 56

La solution acceptée n'a pas fonctionné pour moi, mais cela a fonctionné :

 list = ['x', 'y', 'z']
results = User.objects.filter(first_name__contains=list[0])
del list[0]

for l in list:
    results = results.filter(first_name__contains=l)

La première variable de résultats stockera une liste de tous les objets avec la valeur de champ de nom first_name « x ».

Et puis dans la boucle for vous filtrez pour 'y' parmi les premiers résultats de filtrage. Vous avez maintenant un QuerySet qui devrait contenir une liste d'éléments où « x » et « y » peuvent être trouvés. Maintenant, parmi ceux-ci, vous filtrez également tout élément contenant « z ».

Cela devrait fonctionner pour n'importe quelle liste de longueur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X