Comment dois-je faire une OU filtre dans un Django requête?
Je veux être en mesure de répertorier les éléments qu'un utilisateur a ajouté (ils sont listés en tant que créateur) ou l'article a été approuvé.
J'ai donc besoin de sélectionner:
item.creator = owner or item.moderated = False
Comment faire dans Django? (de préférence avec un filtre ou d'un queryset).
Vous devez vous connecter pour publier un commentaire.
Il est
Q
objets qui permettent de complexe de recherches. Exemple:for f in filters: Item.objects.filter(Q(creator=f1) | Q(creator=f2) | ...)
reduce(lambda q, f: q | Q(creator=f), filters, Q())
pour créer le big Q objet.Item.objects.filter(creator__in=creators)
, par exemple.|
être utilisé comme opérateur vient, c'est en fait l'ensemble de l'union de l'opérateur. Il est également utilisé (pas ici) comme au niveau du bit OU: stackoverflow.com/questions/5988665/pipe-character-in-pythonVous pouvez utiliser l'opérateur | pour combiner querysets directement sans avoir besoin d'objets Q:
(modifier - au départ, j'étais pas sûr si cela a causé une requête supplémentaire mais @spookylukey a souligné que les paresseux queryset d'évaluation qui s'en occupe)
Vous voulez faire de filtre dynamique, alors vous devez utiliser Lambda comme
reduce(lambda x, y: x | y, [Q(brand=item) for item in brands])
est équivalent àfrom functools import reduce
à l'avance.Il est intéressant de noter qu'il est possible d'ajouter des Q expressions.
Par exemple:
Cela finit par une requête du genre :
De cette façon, il n'est pas nécessaire de traiter avec ou opérateurs, de réduire etc.
Similaires à celles des anciens answera, mais un peu plus simple, sans le lambda:
Pour filtrer ces deux conditions à l'aide d'
OR
:Pour obtenir le même résultat par programme:
(cassé en deux lignes ici, pour plus de clarté)
operator
est dans la bibliothèque standard:import operator
De docstring:
Pour Python3,
reduce
n'est pas un builtin plus mais est toujours dans la bibliothèque standard:from functools import reduce
P. S.
N'oubliez pas de assurez-vous
list_of_Q
n'est pas vide -reduce()
va s'étouffer sur la liste est vide, il a besoin d'au moins un élément.Cela peut être utile https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships
Fondamentalement, il sonne comme ils agissent comme OU