mirror of
https://github.com/django/django.git
synced 2025-10-27 23:56:08 +00:00
Subquery deconstruction support required implementing complex and expensive equality rules for sql.Query objects for little benefit as the latter cannot themselves be made deconstructible to their reference to model classes. Making Expression @deconstructible and not BaseExpression allows interested parties to conform to the "expression" API even if they are not deconstructible as it's only a requirement for expressions allowed in Model fields and meta options (e.g. constraints, indexes). Thanks Phillip Cutter for the report. This also fixes a performance regression inbbf141bcdc. Backport ofc8b6594305from main
This commit is contained in:
committed by
Mariusz Felisiak
parent
55cb3c8ac1
commit
d5add5d3a2
@@ -1,4 +1,5 @@
|
||||
from django.db.models import Exists, F, OuterRef, Q
|
||||
from django.db.models import BooleanField, Exists, F, OuterRef, Q
|
||||
from django.db.models.expressions import RawSQL
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
from .models import Tag
|
||||
@@ -37,6 +38,16 @@ class QTests(SimpleTestCase):
|
||||
with self.assertRaisesMessage(TypeError, str(obj)):
|
||||
q & obj
|
||||
|
||||
def test_combine_negated_boolean_expression(self):
|
||||
tagged = Tag.objects.filter(category=OuterRef('pk'))
|
||||
tests = [
|
||||
Q() & ~Exists(tagged),
|
||||
Q() | ~Exists(tagged),
|
||||
]
|
||||
for q in tests:
|
||||
with self.subTest(q=q):
|
||||
self.assertIs(q.negated, True)
|
||||
|
||||
def test_deconstruct(self):
|
||||
q = Q(price__gt=F('discounted_price'))
|
||||
path, args, kwargs = q.deconstruct()
|
||||
@@ -88,10 +99,10 @@ class QTests(SimpleTestCase):
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
def test_deconstruct_boolean_expression(self):
|
||||
tagged = Tag.objects.filter(category=OuterRef('pk'))
|
||||
q = Q(Exists(tagged))
|
||||
expr = RawSQL('1 = 1', BooleanField())
|
||||
q = Q(expr)
|
||||
_, args, kwargs = q.deconstruct()
|
||||
self.assertEqual(args, (Exists(tagged),))
|
||||
self.assertEqual(args, (expr,))
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
def test_reconstruct(self):
|
||||
|
||||
Reference in New Issue
Block a user