summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-09-14 16:03:52 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-09-18 22:12:40 +0200
commit5e4c1793b714a975400b9277a66f99efafa2d92c (patch)
treed2d0e165f563a1f25534751245c6e921442d7a1e
parent69af3bea9987044c944b5bc83e32c35f0a73c6dd (diff)
Refs #33308 -- Removed support for passing encoded JSON string literals to JSONField & co.
Per deprecation timeline.
-rw-r--r--django/contrib/postgres/aggregates/general.py33
-rw-r--r--django/db/models/fields/json.py31
-rw-r--r--docs/releases/5.1.txt3
-rw-r--r--docs/topics/db/queries.txt4
-rw-r--r--tests/model_fields/test_jsonfield.py25
-rw-r--r--tests/postgres_tests/test_aggregates.py56
6 files changed, 8 insertions, 144 deletions
diff --git a/django/contrib/postgres/aggregates/general.py b/django/contrib/postgres/aggregates/general.py
index c8eea1034d..5de53676f6 100644
--- a/django/contrib/postgres/aggregates/general.py
+++ b/django/contrib/postgres/aggregates/general.py
@@ -1,9 +1,5 @@
-import json
-import warnings
-
from django.contrib.postgres.fields import ArrayField
from django.db.models import Aggregate, BooleanField, JSONField, TextField, Value
-from django.utils.deprecation import RemovedInDjango51Warning
from .mixins import OrderableAggMixin
@@ -57,35 +53,6 @@ class JSONBAgg(OrderableAggMixin, Aggregate):
allow_distinct = True
output_field = JSONField()
- # RemovedInDjango51Warning: When the deprecation ends, remove __init__().
- def __init__(self, *expressions, default=None, **extra):
- super().__init__(*expressions, default=default, **extra)
- if (
- isinstance(default, Value)
- and isinstance(default.value, str)
- and not isinstance(default.output_field, JSONField)
- ):
- value = default.value
- try:
- decoded = json.loads(value)
- except json.JSONDecodeError:
- warnings.warn(
- "Passing a Value() with an output_field that isn't a JSONField as "
- "JSONBAgg(default) is deprecated. Pass default="
- f"Value({value!r}, output_field=JSONField()) instead.",
- stacklevel=2,
- category=RemovedInDjango51Warning,
- )
- self.default.output_field = self.output_field
- else:
- self.default = Value(decoded, self.output_field)
- warnings.warn(
- "Passing an encoded JSON string as JSONBAgg(default) is "
- f"deprecated. Pass default={decoded!r} instead.",
- stacklevel=2,
- category=RemovedInDjango51Warning,
- )
-
class StringAgg(OrderableAggMixin, Aggregate):
function = "STRING_AGG"
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py
index b7cde157c4..7b9b2ae6b2 100644
--- a/django/db/models/fields/json.py
+++ b/django/db/models/fields/json.py
@@ -1,5 +1,4 @@
import json
-import warnings
from django import forms
from django.core import checks, exceptions
@@ -12,7 +11,6 @@ from django.db.models.lookups import (
PostgresOperatorLookup,
Transform,
)
-from django.utils.deprecation import RemovedInDjango51Warning
from django.utils.translation import gettext_lazy as _
from . import Field
@@ -101,31 +99,10 @@ class JSONField(CheckFieldDefaultMixin, Field):
def get_db_prep_value(self, value, connection, prepared=False):
if not prepared:
value = self.get_prep_value(value)
- # RemovedInDjango51Warning: When the deprecation ends, replace with:
- # if (
- # isinstance(value, expressions.Value)
- # and isinstance(value.output_field, JSONField)
- # ):
- # value = value.value
- # elif hasattr(value, "as_sql"): ...
- if isinstance(value, expressions.Value):
- if isinstance(value.value, str) and not isinstance(
- value.output_field, JSONField
- ):
- try:
- value = json.loads(value.value, cls=self.decoder)
- except json.JSONDecodeError:
- value = value.value
- else:
- warnings.warn(
- "Providing an encoded JSON string via Value() is deprecated. "
- f"Use Value({value!r}, output_field=JSONField()) instead.",
- category=RemovedInDjango51Warning,
- )
- elif isinstance(value.output_field, JSONField):
- value = value.value
- else:
- return value
+ if isinstance(value, expressions.Value) and isinstance(
+ value.output_field, JSONField
+ ):
+ value = value.value
elif hasattr(value, "as_sql"):
return value
return connection.ops.adapt_json_value(value, self.encoder)
diff --git a/docs/releases/5.1.txt b/docs/releases/5.1.txt
index 4ed51d288e..2ca8a492ca 100644
--- a/docs/releases/5.1.txt
+++ b/docs/releases/5.1.txt
@@ -274,3 +274,6 @@ to remove usage of these features.
* The ``SimpleTestCase.assertFormsetError()`` method is removed.
* The ``TransactionTestCase.assertQuerysetEqual()`` method is removed.
+
+* Support for passing encoded JSON string literals to ``JSONField`` and
+ associated lookups and expressions is removed.
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
index b975f6cdfe..3f7031c2ab 100644
--- a/docs/topics/db/queries.txt
+++ b/docs/topics/db/queries.txt
@@ -1085,10 +1085,6 @@ Unless you are sure you wish to work with SQL ``NULL`` values, consider setting
Storing JSON scalar ``null`` does not violate :attr:`null=False
<django.db.models.Field.null>`.
-.. deprecated:: 4.2
-
- Passing ``Value("null")`` to express JSON ``null`` is deprecated.
-
.. fieldlookup:: jsonfield.key
Key, index, and path transforms
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index 4a1cc075b4..40836aece7 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -37,7 +37,6 @@ from django.db.models.fields.json import (
from django.db.models.functions import Cast
from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature
from django.test.utils import CaptureQueriesContext
-from django.utils.deprecation import RemovedInDjango51Warning
from .models import CustomJSONDecoder, JSONModel, NullableJSONModel, RelatedJSONModel
@@ -216,30 +215,6 @@ class TestSaveLoad(TestCase):
obj.refresh_from_db()
self.assertIsNone(obj.value)
- def test_ambiguous_str_value_deprecation(self):
- msg = (
- "Providing an encoded JSON string via Value() is deprecated. Use Value([], "
- "output_field=JSONField()) instead."
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- obj = NullableJSONModel.objects.create(value=Value("[]"))
- obj.refresh_from_db()
- self.assertEqual(obj.value, [])
-
- @skipUnlessDBFeature("supports_primitives_in_json_field")
- def test_value_str_primitives_deprecation(self):
- msg = (
- "Providing an encoded JSON string via Value() is deprecated. Use "
- "Value(None, output_field=JSONField()) instead."
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- obj = NullableJSONModel.objects.create(value=Value("null"))
- obj.refresh_from_db()
- self.assertIsNone(obj.value)
- obj = NullableJSONModel.objects.create(value=Value("invalid-json"))
- obj.refresh_from_db()
- self.assertEqual(obj.value, "invalid-json")
-
@skipUnlessDBFeature("supports_primitives_in_json_field")
def test_json_null_different_from_sql_null(self):
json_null = NullableJSONModel.objects.create(value=Value(None, JSONField()))
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py
index bb694dae63..386c55da25 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -14,9 +14,8 @@ from django.db.models import (
from django.db.models.fields.json import KeyTextTransform, KeyTransform
from django.db.models.functions import Cast, Concat, Substr
from django.test import skipUnlessDBFeature
-from django.test.utils import Approximate, ignore_warnings
+from django.test.utils import Approximate
from django.utils import timezone
-from django.utils.deprecation import RemovedInDjango51Warning
from . import PostgreSQLTestCase
from .models import AggregateTestModel, HotelReservation, Room, StatTestModel
@@ -152,59 +151,6 @@ class TestGeneralAggregate(PostgreSQLTestCase):
)
self.assertEqual(values, {"aggregation": expected_result})
- @ignore_warnings(category=RemovedInDjango51Warning)
- def test_jsonb_agg_default_str_value(self):
- AggregateTestModel.objects.all().delete()
- queryset = AggregateTestModel.objects.all()
- self.assertEqual(
- queryset.aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("<empty>"))
- ),
- {"aggregation": "<empty>"},
- )
-
- def test_jsonb_agg_default_str_value_deprecation(self):
- queryset = AggregateTestModel.objects.all()
- msg = (
- "Passing a Value() with an output_field that isn't a JSONField as "
- "JSONBAgg(default) is deprecated. Pass default=Value('<empty>', "
- "output_field=JSONField()) instead."
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- queryset.aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("<empty>"))
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- queryset.none().aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("<empty>"))
- ),
-
- @ignore_warnings(category=RemovedInDjango51Warning)
- def test_jsonb_agg_default_encoded_json_string(self):
- AggregateTestModel.objects.all().delete()
- queryset = AggregateTestModel.objects.all()
- self.assertEqual(
- queryset.aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("[]"))
- ),
- {"aggregation": []},
- )
-
- def test_jsonb_agg_default_encoded_json_string_deprecation(self):
- queryset = AggregateTestModel.objects.all()
- msg = (
- "Passing an encoded JSON string as JSONBAgg(default) is deprecated. Pass "
- "default=[] instead."
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- queryset.aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("[]"))
- )
- with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
- queryset.none().aggregate(
- aggregation=JSONBAgg("integer_field", default=Value("[]"))
- )
-
def test_array_agg_charfield(self):
values = AggregateTestModel.objects.aggregate(arrayagg=ArrayAgg("char_field"))
self.assertEqual(values, {"arrayagg": ["Foo1", "Foo2", "Foo4", "Foo3"]})