1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

Refs #30581 -- Added Q.flatten().

This commit is contained in:
Gagaro 2022-05-03 14:06:42 +02:00 committed by Mariusz Felisiak
parent df22566748
commit 9d04711261
2 changed files with 42 additions and 1 deletions

View File

@ -95,6 +95,21 @@ class Q(tree.Node):
query.promote_joins(joins) query.promote_joins(joins)
return clause return clause
def flatten(self):
"""
Recursively yield this Q object and all subexpressions, in depth-first
order.
"""
yield self
for child in self.children:
if isinstance(child, tuple):
# Use the lookup.
child = child[1]
if hasattr(child, "flatten"):
yield from child.flatten()
else:
yield child
def deconstruct(self): def deconstruct(self):
path = "%s.%s" % (self.__class__.__module__, self.__class__.__name__) path = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
if path.startswith("django.db.models.query_utils"): if path.startswith("django.db.models.query_utils"):

View File

@ -1,5 +1,15 @@
from django.db.models import BooleanField, Exists, F, OuterRef, Q from django.db.models import (
BooleanField,
Exists,
ExpressionWrapper,
F,
OuterRef,
Q,
Value,
)
from django.db.models.expressions import RawSQL from django.db.models.expressions import RawSQL
from django.db.models.functions import Lower
from django.db.models.sql.where import NothingNode
from django.test import SimpleTestCase from django.test import SimpleTestCase
from .models import Tag from .models import Tag
@ -188,3 +198,19 @@ class QTests(SimpleTestCase):
q = q1 & q2 q = q1 & q2
path, args, kwargs = q.deconstruct() path, args, kwargs = q.deconstruct()
self.assertEqual(Q(*args, **kwargs), q) self.assertEqual(Q(*args, **kwargs), q)
def test_flatten(self):
q = Q()
self.assertEqual(list(q.flatten()), [q])
q = Q(NothingNode())
self.assertEqual(list(q.flatten()), [q, q.children[0]])
q = Q(
ExpressionWrapper(
Q(RawSQL("id = 0", params=(), output_field=BooleanField()))
| Q(price=Value("4.55"))
| Q(name=Lower("category")),
output_field=BooleanField(),
)
)
flatten = list(q.flatten())
self.assertEqual(len(flatten), 7)