summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsage <laymonage@gmail.com>2020-11-18 11:50:06 +0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-11-25 14:51:35 +0100
commitfe6e5824218bab7cf47dee112d68325b338f9947 (patch)
treebf1685c4795a2645362d51da334495839249f434
parent7408c4cd157ae18971302a2baf7aacce7c204a09 (diff)
Fixed #32203 -- Fixed QuerySet.values()/values_list() crash on key transforms with non-string values on SQLite.
Thanks Gordon Wrigley for the report.
-rw-r--r--django/db/models/fields/json.py4
-rw-r--r--docs/releases/3.1.4.txt4
-rw-r--r--tests/model_fields/test_jsonfield.py5
3 files changed, 13 insertions, 0 deletions
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py
index 48512ce59c..340b7ee875 100644
--- a/django/db/models/fields/json.py
+++ b/django/db/models/fields/json.py
@@ -75,6 +75,10 @@ class JSONField(CheckFieldDefaultMixin, Field):
def from_db_value(self, value, expression, connection):
if value is None:
return value
+ # Some backends (SQLite at least) extract non-string values in their
+ # SQL datatypes.
+ if isinstance(expression, KeyTransform) and not isinstance(value, str):
+ return value
try:
return json.loads(value, cls=self.decoder)
except json.JSONDecodeError:
diff --git a/docs/releases/3.1.4.txt b/docs/releases/3.1.4.txt
index 080db4f290..74e679cb8c 100644
--- a/docs/releases/3.1.4.txt
+++ b/docs/releases/3.1.4.txt
@@ -28,3 +28,7 @@ Bugfixes
* Fixed a regression in Django 3.1 that caused suppressing connection errors
when :class:`~django.db.models.JSONField` is used on SQLite
(:ticket:`32224`).
+
+* Fixed a crash on SQLite, when ``QuerySet.values()/values_list()`` contained
+ key transforms for :class:`~django.db.models.JSONField` returning non-string
+ primitive values (:ticket:`32203`).
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index 23479b4c0d..c1bacbe750 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -277,6 +277,7 @@ class TestQuerying(TestCase):
'k': {'l': 'm'},
'n': [None],
'o': '"quoted"',
+ 'p': 4.2,
},
[1, [2]],
{'k': True, 'l': False, 'foo': 'bax'},
@@ -753,10 +754,14 @@ class TestQuerying(TestCase):
qs = NullableJSONModel.objects.filter(value__h=True)
tests = [
('value__a', 'b'),
+ ('value__c', 14),
('value__d', ['e', {'f': 'g'}]),
+ ('value__h', True),
+ ('value__i', False),
('value__j', None),
('value__k', {'l': 'm'}),
('value__n', [None]),
+ ('value__p', 4.2),
]
for lookup, expected in tests:
with self.subTest(lookup=lookup):