Fixed #32203 -- Fixed QuerySet.values()/values_list() crash on key transforms with non-string values on SQLite.
Thanks Gordon Wrigley for the report.
This commit is contained in:
parent
7408c4cd15
commit
fe6e582421
|
@ -75,6 +75,10 @@ class JSONField(CheckFieldDefaultMixin, Field):
|
||||||
def from_db_value(self, value, expression, connection):
|
def from_db_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
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:
|
try:
|
||||||
return json.loads(value, cls=self.decoder)
|
return json.loads(value, cls=self.decoder)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
|
|
|
@ -28,3 +28,7 @@ Bugfixes
|
||||||
* Fixed a regression in Django 3.1 that caused suppressing connection errors
|
* Fixed a regression in Django 3.1 that caused suppressing connection errors
|
||||||
when :class:`~django.db.models.JSONField` is used on SQLite
|
when :class:`~django.db.models.JSONField` is used on SQLite
|
||||||
(:ticket:`32224`).
|
(: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`).
|
||||||
|
|
|
@ -277,6 +277,7 @@ class TestQuerying(TestCase):
|
||||||
'k': {'l': 'm'},
|
'k': {'l': 'm'},
|
||||||
'n': [None],
|
'n': [None],
|
||||||
'o': '"quoted"',
|
'o': '"quoted"',
|
||||||
|
'p': 4.2,
|
||||||
},
|
},
|
||||||
[1, [2]],
|
[1, [2]],
|
||||||
{'k': True, 'l': False, 'foo': 'bax'},
|
{'k': True, 'l': False, 'foo': 'bax'},
|
||||||
|
@ -753,10 +754,14 @@ class TestQuerying(TestCase):
|
||||||
qs = NullableJSONModel.objects.filter(value__h=True)
|
qs = NullableJSONModel.objects.filter(value__h=True)
|
||||||
tests = [
|
tests = [
|
||||||
('value__a', 'b'),
|
('value__a', 'b'),
|
||||||
|
('value__c', 14),
|
||||||
('value__d', ['e', {'f': 'g'}]),
|
('value__d', ['e', {'f': 'g'}]),
|
||||||
|
('value__h', True),
|
||||||
|
('value__i', False),
|
||||||
('value__j', None),
|
('value__j', None),
|
||||||
('value__k', {'l': 'm'}),
|
('value__k', {'l': 'm'}),
|
||||||
('value__n', [None]),
|
('value__n', [None]),
|
||||||
|
('value__p', 4.2),
|
||||||
]
|
]
|
||||||
for lookup, expected in tests:
|
for lookup, expected in tests:
|
||||||
with self.subTest(lookup=lookup):
|
with self.subTest(lookup=lookup):
|
||||||
|
|
Loading…
Reference in New Issue