mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Refs #33308 -- Removed support for passing encoded JSON string literals to JSONField & co.
Per deprecation timeline.
This commit is contained in:
parent
69af3bea99
commit
5e4c1793b7
@ -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"
|
||||
|
@ -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(
|
||||
if isinstance(value, expressions.Value) and 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
|
||||
elif hasattr(value, "as_sql"):
|
||||
return value
|
||||
return connection.ops.adapt_json_value(value, self.encoder)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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()))
|
||||
|
@ -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"]})
|
||||
|
Loading…
Reference in New Issue
Block a user