Plusieurs façons de le faire.
1. En utilisant directement l'opérateur pipe |.
from django.db.models import Q
Items.objects.filter(Q(field1=value) | Q(field2=value))
2. En utilisant la méthode __or__
.
Items.objects.filter(Q(field1=value).__or__(field2=value))
3. En modifiant l'opération par défaut. (Faites attention à réinitialiser le comportement par défaut)
Q.default = Q.OR # Non recommandé (Q.AND est le comportement par défaut)
Items.objects.filter(Q(field1=value, field2=value))
Q.default = Q.AND # Réinitialiser après utilisation.
4. En utilisant l'argument de classe _connector
de Q
.
logic = Q(field1=value, field2=value, field3=value, _connector=Q.OR)
Item.objects.filter(logic)
Snapshot de l'implémentation de Q
class Q(tree.Node):
"""
Encapsule les filtres comme des objets qui peuvent ensuite être combinés logiquement (en utilisant
`&` et `|`).
"""
# Types de connexion
AND = 'AND'
OR = 'OR'
default = AND
conditional = True
def __init__(self, *args, _connector=None, _negated=False, **kwargs):
super().__init__(children=[*args, *sorted(kwargs.items())], connector=_connector, negated=_negated)
def _combine(self, other, conn):
if not(isinstance(other, Q) or getattr(other, 'conditional', False) is True):
raise TypeError(other)
if not self:
return other.copy() if hasattr(other, 'copy') else copy.copy(other)
elif isinstance(other, Q) and not other:
_, args, kwargs = self.deconstruct()
return type(self)(*args, **kwargs)
obj = type(self)()
obj.connector = conn
obj.add(self, conn)
obj.add(other, conn)
return obj
def __or__(self, other):
return self._combine(other, self.OR)
def __and__(self, other):
return self._combine(other, self.AND)
.............
Réf. Implémentation de Q