Q Expression container. Q Expressions are a useful tool to compose a query from many small parts. :param join_type: Is the join an AND or OR join type? :param args: Inner ``Q`` expressions that you want to wrap. :param kwargs: Filter statements that this Q object should encapsu
| 253 | |
| 254 | |
| 255 | class Q: |
| 256 | """ |
| 257 | Q Expression container. |
| 258 | Q Expressions are a useful tool to compose a query from many small parts. |
| 259 | |
| 260 | :param join_type: Is the join an AND or OR join type? |
| 261 | :param args: Inner ``Q`` expressions that you want to wrap. |
| 262 | :param kwargs: Filter statements that this Q object should encapsulate. |
| 263 | """ |
| 264 | |
| 265 | __slots__ = ( |
| 266 | "children", |
| 267 | "filters", |
| 268 | "join_type", |
| 269 | "_is_negated", |
| 270 | ) |
| 271 | |
| 272 | AND = "AND" |
| 273 | OR = "OR" |
| 274 | |
| 275 | def __init__(self, *args: Q, join_type: str = AND, **kwargs: Any) -> None: |
| 276 | if args and kwargs: |
| 277 | newarg = Q(join_type=join_type, **kwargs) |
| 278 | args = (newarg,) + args |
| 279 | kwargs = {} |
| 280 | if not all(isinstance(node, Q) for node in args): |
| 281 | raise OperationalError("All ordered arguments must be Q nodes") |
| 282 | #: Contains the sub-Q's that this Q is made up of |
| 283 | self.children: tuple[Q, ...] = args |
| 284 | #: Contains the filters applied to this Q |
| 285 | self.filters: dict[str, FilterInfoDict] = kwargs |
| 286 | if join_type not in {self.AND, self.OR}: |
| 287 | raise OperationalError("join_type must be AND or OR") |
| 288 | #: Specifies if this Q does an AND or OR on its children |
| 289 | self.join_type = join_type |
| 290 | self._is_negated = False |
| 291 | |
| 292 | def __and__(self, other: Q) -> Q: |
| 293 | """ |
| 294 | Returns a binary AND of Q objects, use ``AND`` operator. |
| 295 | |
| 296 | :raises OperationalError: AND operation requires a Q node |
| 297 | """ |
| 298 | if not isinstance(other, Q): |
| 299 | raise OperationalError("AND operation requires a Q node") |
| 300 | return Q(self, other, join_type=self.AND) |
| 301 | |
| 302 | def __or__(self, other: Q) -> Q: |
| 303 | """ |
| 304 | Returns a binary OR of Q objects, use ``OR`` operator. |
| 305 | |
| 306 | :raises OperationalError: OR operation requires a Q node |
| 307 | """ |
| 308 | if not isinstance(other, Q): |
| 309 | raise OperationalError("OR operation requires a Q node") |
| 310 | return Q(self, other, join_type=self.OR) |
| 311 | |
| 312 | def __invert__(self) -> Q: |
no outgoing calls