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):