Fixed #29125 -- Made Q.deconstruct() deterministic with multiple keyword arguments.
This commit is contained in:
parent
a6fb81750a
commit
b95c49c954
|
@ -58,7 +58,7 @@ class Q(tree.Node):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
connector = kwargs.pop('_connector', None)
|
connector = kwargs.pop('_connector', None)
|
||||||
negated = kwargs.pop('_negated', False)
|
negated = kwargs.pop('_negated', False)
|
||||||
super().__init__(children=list(args) + list(kwargs.items()), connector=connector, negated=negated)
|
super().__init__(children=list(args) + sorted(kwargs.items()), connector=connector, negated=negated)
|
||||||
|
|
||||||
def _combine(self, other, conn):
|
def _combine(self, other, conn):
|
||||||
if not isinstance(other, Q):
|
if not isinstance(other, Q):
|
||||||
|
|
|
@ -17,3 +17,7 @@ Bugfixes
|
||||||
(:ticket:`29109`).
|
(:ticket:`29109`).
|
||||||
|
|
||||||
* Fixed crash with ``QuerySet.order_by(Exists(...))`` (:ticket:`29118`).
|
* Fixed crash with ``QuerySet.order_by(Exists(...))`` (:ticket:`29118`).
|
||||||
|
|
||||||
|
* Made ``Q.deconstruct()`` deterministic with multiple keyword arguments
|
||||||
|
(:ticket:`29125`). You may need to modify ``Q``'s in existing migrations, or
|
||||||
|
accept an autogenerated migration.
|
||||||
|
|
|
@ -60,6 +60,15 @@ class QTests(SimpleTestCase):
|
||||||
))
|
))
|
||||||
self.assertEqual(kwargs, {'_connector': 'AND'})
|
self.assertEqual(kwargs, {'_connector': 'AND'})
|
||||||
|
|
||||||
|
def test_deconstruct_multiple_kwargs(self):
|
||||||
|
q = Q(price__gt=F('discounted_price'), price=F('discounted_price'))
|
||||||
|
path, args, kwargs = q.deconstruct()
|
||||||
|
self.assertEqual(args, (
|
||||||
|
('price', F('discounted_price')),
|
||||||
|
('price__gt', F('discounted_price')),
|
||||||
|
))
|
||||||
|
self.assertEqual(kwargs, {'_connector': 'AND'})
|
||||||
|
|
||||||
def test_deconstruct_nested(self):
|
def test_deconstruct_nested(self):
|
||||||
q = Q(Q(price__gt=F('discounted_price')))
|
q = Q(Q(price__gt=F('discounted_price')))
|
||||||
path, args, kwargs = q.deconstruct()
|
path, args, kwargs = q.deconstruct()
|
||||||
|
|
Loading…
Reference in New Issue