À partir d'un exemple, vous pouvez voir un filtre de requête OR multiple:
Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Par exemple, cela se traduit par:
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
Cependant, je souhaite créer ce filtre de requête à partir d'une liste. Comment faire ça?
par exemple [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Article.objects.filter(pk__in=[1, 2, 3])
dans django moderne, mais la question est toujours pertinente si vous voulez faire quelque chose d'un peu plus avancé en OR'ing Q objets ensemble.Réponses:
Vous pouvez enchaîner vos requêtes comme suit:
la source
Pour créer des requêtes plus complexes, il existe également la possibilité d'utiliser les constantes Q.OR et Q.AND de l'objet Q () intégré avec la méthode add () comme ceci:
la source
q_objects |= Q(pk=item)
list
vous êtes vide, vous retournerez l'équivalent deArticle.objects.all()
. Facile à atténuer en revenantArticle.objects.none()
pour ce test cependant.q_objects
avecQ(id__in=[])
. Il échouera toujours à moins que OU avec quelque chose et l'optimiseur de requête le gérera bien.Une façon plus courte d'écrire la réponse de Dave Webb en utilisant la fonction de réduction de python :
la source
functools.reduce
. sourceoperator.or_
place du lambda.la source
operator
?Il est peut-être préférable d'utiliser l'instruction SQL IN.
Voir la référence de l'API queryset .
Si vous avez vraiment besoin de faire des requêtes avec une logique dynamique, vous pouvez faire quelque chose comme ça (moche + non testé):
la source
query |= Q(field=cond)
Voir la documentation :
Notez que cette méthode ne fonctionne que pour les recherches de clé primaire, mais cela semble être ce que vous essayez de faire.
Donc ce que vous voulez c'est:
la source
Si nous voulons définir par programme le champ de base de données que nous voulons interroger:
la source
Solution qui utilise
reduce
etor_
opérateurs pour filtrer par multi-champs.ps
f
est un nouveau format littéral de chaînes. Il a été introduit dans python 3.6la source
Vous pouvez utiliser l'opérateur | = pour mettre à jour par programme une requête à l'aide d'objets Q.
la source
Celui-ci est pour la liste pk dynamique:
la source
q = Q()
place deq = None
, puis supprimer laif q is None
clause - légèrement moins efficace mais peut supprimer trois lignes de code. (Le Q vide est ensuite fusionné lorsque la requête est exécutée.)Une autre option que je ne le savais pas jusqu'à récemment -
QuerySet
remplace également les&
,|
,~
, etc, opérateurs. Les autres réponses que les objets OR Q sont une meilleure solution à cette question, mais par souci d'intérêt / argument, vous pouvez faire:str(q.query)
renverra une requête avec tous les filtres de laWHERE
clause.la source
Pour la boucle:
Réduire:
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 avecQ()
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).Si vous voulez tout renvoyer quand il
values
est vide, vous devez ET avec~Q(pk__in=[])
pour vous assurer que le comportement: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.la source
facile ..
de django.db.models importez Q importez vous modélisez args = (Q (visibilité = 1) | (Q (visibilité = 0) & Q (utilisateur = self.user))) #Tuple parameters = {} #dic order = limite 'create_at' = 10
la source