summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouise Grandjonc <louve.grandjonc@gmail.com>2019-10-01 16:25:40 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-10-11 11:52:32 +0200
commit323467e286787684de18d2731776c71667a296be (patch)
tree2b4914f786873686e1554bea95343a3757bf7b5b
parent4f7ba25e67681efbb67cc4810e919aa7369cbe34 (diff)
downloaddjango-323467e286787684de18d2731776c71667a296be.tar.gz
[2.2.x] Fixed #30826 -- Fixed crash of many JSONField lookups when one hand side is key transform.
Regression in 6c3dfba89215fc56fc27ef61829a6fff88be4abb. Backport of 7d1bf29977bb368d7c28e7c6eb146db3b3009ae7 from master
-rw-r--r--django/contrib/postgres/lookups.py2
-rw-r--r--docs/releases/1.11.26.txt5
-rw-r--r--docs/releases/2.1.14.txt5
-rw-r--r--docs/releases/2.2.7.txt5
-rw-r--r--tests/postgres_tests/test_json.py27
5 files changed, 39 insertions, 5 deletions
diff --git a/django/contrib/postgres/lookups.py b/django/contrib/postgres/lookups.py
index c2b3d2b569..ac8d3bc522 100644
--- a/django/contrib/postgres/lookups.py
+++ b/django/contrib/postgres/lookups.py
@@ -8,7 +8,7 @@ class PostgresSimpleLookup(Lookup):
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
- params = lhs_params + rhs_params
+ params = tuple(lhs_params) + tuple(rhs_params)
return '%s %s %s' % (lhs, self.operator, rhs), params
diff --git a/docs/releases/1.11.26.txt b/docs/releases/1.11.26.txt
index a0c39b4168..1a54b47e1b 100644
--- a/docs/releases/1.11.26.txt
+++ b/docs/releases/1.11.26.txt
@@ -9,4 +9,7 @@ Django 1.11.26 fixes a regression in 1.11.25.
Bugfixes
========
-* ...
+* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
+ ``has_keys``, or ``has_any_keys`` lookup on
+ :class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
+ side of an expression is a key transform (:ticket:`30826`).
diff --git a/docs/releases/2.1.14.txt b/docs/releases/2.1.14.txt
index 17b001e4e5..92354462a0 100644
--- a/docs/releases/2.1.14.txt
+++ b/docs/releases/2.1.14.txt
@@ -9,4 +9,7 @@ Django 2.1.14 fixes a regression in 2.1.13.
Bugfixes
========
-* ...
+* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
+ ``has_keys``, or ``has_any_keys`` lookup on
+ :class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
+ side of an expression is a key transform (:ticket:`30826`).
diff --git a/docs/releases/2.2.7.txt b/docs/releases/2.2.7.txt
index 001af88176..f39587e43e 100644
--- a/docs/releases/2.2.7.txt
+++ b/docs/releases/2.2.7.txt
@@ -9,4 +9,7 @@ Django 2.2.7 fixes several bugs in 2.2.6.
Bugfixes
========
-* ...
+* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
+ ``has_keys``, or ``has_any_keys`` lookup on
+ :class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
+ side of an expression is a key transform (:ticket:`30826`).
diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py
index a74a5f8dde..8a4584eda6 100644
--- a/tests/postgres_tests/test_json.py
+++ b/tests/postgres_tests/test_json.py
@@ -126,7 +126,12 @@ class TestQuerying(PostgreSQLTestCase):
'k': True,
'l': False,
}),
- JSONModel(field={'foo': 'bar'}),
+ JSONModel(field={
+ 'foo': 'bar',
+ 'baz': {'a': 'b', 'c': 'd'},
+ 'bar': ['foo', 'bar'],
+ 'bax': {'foo': 'bar'},
+ }),
])
def test_exact(self):
@@ -361,6 +366,26 @@ class TestQuerying(PostgreSQLTestCase):
queries[0]['sql'],
)
+ def test_lookups_with_key_transform(self):
+ tests = (
+ ('field__d__contains', 'e'),
+ ('field__baz__contained_by', {'a': 'b', 'c': 'd', 'e': 'f'}),
+ ('field__baz__has_key', 'c'),
+ ('field__baz__has_keys', ['a', 'c']),
+ ('field__baz__has_any_keys', ['a', 'x']),
+ ('field__contains', KeyTransform('bax', 'field')),
+ (
+ 'field__contained_by',
+ KeyTransform('x', RawSQL('%s::jsonb', ['{"x": {"a": "b", "c": 1, "d": "e"}}'])),
+ ),
+ ('field__has_key', KeyTextTransform('foo', 'field')),
+ )
+ for lookup, value in tests:
+ with self.subTest(lookup=lookup):
+ self.assertTrue(JSONModel.objects.filter(
+ **{lookup: value},
+ ).exists())
+
@isolate_apps('postgres_tests')
class TestChecks(PostgreSQLSimpleTestCase):