Pour la boucle:
values = [1, 2, 3]
q = Q(pk__in=[]) # generic "always false" value
for val in values:
q |= Q(pk=val)
Article.objects.filter(q)
Réduire:
from functools import reduce
from operator import or_
values = [1, 2, 3]
q_objects = [Q(pk=val) for val in values]
q = reduce(or_, q_objects, Q(pk__in=[]))
Article.objects.filter(q)
Les deux sont équivalents à Article.objects.filter(pk__in=values)
Il est important de considérer ce que vous voulez quand il values
est vide. De nombreuses réponses avec Q()
comme valeur de départ renverront tout . Q(pk__in=[])
est une meilleure valeur de départ. C'est un objet Q toujours en échec qui est bien géré par l'optimiseur (même pour les équations complexes).
Article.objects.filter(Q(pk__in=[])) # doesn't hit DB
Article.objects.filter(Q(pk=None)) # hits DB and returns nothing
Article.objects.none() # doesn't hit DB
Article.objects.filter(Q()) # returns everything
Si vous voulez tout renvoyer quand il values
est vide, vous devez ET avec ~Q(pk__in=[])
pour vous assurer que le comportement:
values = []
q = Q()
for val in values:
q |= Q(pk=val)
Article.objects.filter(q) # everything
Article.objects.filter(q | author="Tolkien") # only Tolkien
q &= ~Q(pk__in=[])
Article.objects.filter(q) # everything
Article.objects.filter(q | author="Tolkien") # everything
Il est important de se rappeler que ce Q()
n'est rien , pas un objet Q qui se succède toujours. Toute opération l'impliquant la laissera tomber complètement.