From 0ff46591ac3010841c73fd26e0fef93995fedd99 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Wed, 2 Nov 2022 22:03:05 -0400 Subject: Refs #33308 -- Deprecated support for passing encoded JSON string literals to JSONField & co. JSON should be provided as literal Python objects an not in their encoded string literal forms. --- docs/internals/deprecation.txt | 3 +++ docs/releases/4.2.txt | 36 ++++++++++++++++++++++++++++++++++++ docs/topics/db/queries.txt | 17 ++++++++++++++--- 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index abd5a363bc..02a12f0823 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -39,6 +39,9 @@ details on these changes. * The ``TransactionTestCase.assertQuerysetEqual()`` method will be removed. +* Support for passing encoded JSON string literals to ``JSONField`` and + associated lookups and expressions will be removed. + .. _deprecation-removed-in-5.0: 5.0 diff --git a/docs/releases/4.2.txt b/docs/releases/4.2.txt index 8153eefebc..054f8d6621 100644 --- a/docs/releases/4.2.txt +++ b/docs/releases/4.2.txt @@ -444,6 +444,42 @@ but it should not be used for new migrations. Use :class:`~django.db.migrations.operations.AddIndex` and :class:`~django.db.migrations.operations.RemoveIndex` operations instead. +Passing encoded JSON string literals to ``JSONField`` is deprecated +------------------------------------------------------------------- + +``JSONField`` and its associated lookups and aggregates use to allow passing +JSON encoded string literals which caused ambiguity on whether string literals +were already encoded from database backend's perspective. + +During the deprecation period string literals will be attempted to be JSON +decoded and a warning will be emitted on success that points at passing +non-encoded forms instead. + +Code that use to pass JSON encoded string literals:: + + Document.objects.bulk_create( + Document(data=Value("null")), + Document(data=Value("[]")), + Document(data=Value('"foo-bar"')), + ) + Document.objects.annotate( + JSONBAgg("field", default=Value('[]')), + ) + +Should become:: + + Document.objects.bulk_create( + Document(data=Value(None, JSONField())), + Document(data=[]), + Document(data="foo-bar"), + ) + Document.objects.annotate( + JSONBAgg("field", default=[]), + ) + +From Django 5.1+ string literals will be implicitly interpreted as JSON string +literals. + Miscellaneous ------------- diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index 5114efb57d..977e287c53 100644 --- a/docs/topics/db/queries.txt +++ b/docs/topics/db/queries.txt @@ -971,7 +971,7 @@ Storing and querying for ``None`` As with other fields, storing ``None`` as the field's value will store it as SQL ``NULL``. While not recommended, it is possible to store JSON scalar -``null`` instead of SQL ``NULL`` by using :class:`Value('null') +``null`` instead of SQL ``NULL`` by using :class:`Value(None, JSONField()) `. Whichever of the values is stored, when retrieved from the database, the Python @@ -987,11 +987,13 @@ query for SQL ``NULL``, use :lookup:`isnull`:: >>> Dog.objects.create(name='Max', data=None) # SQL NULL. - >>> Dog.objects.create(name='Archie', data=Value('null')) # JSON null. + >>> Dog.objects.create( + ... name='Archie', data=Value(None, JSONField()) # JSON null. + ... ) >>> Dog.objects.filter(data=None) ]> - >>> Dog.objects.filter(data=Value('null')) + >>> Dog.objects.filter(data=Value(None, JSONField()) ]> >>> Dog.objects.filter(data__isnull=True) ]> @@ -1007,6 +1009,15 @@ Unless you are sure you wish to work with SQL ``NULL`` values, consider setting Storing JSON scalar ``null`` does not violate :attr:`null=False `. +.. versionchanged:: 4.2 + + Support for expressing JSON ``null`` using ``Value(None, JSONField())`` was + added. + +.. deprecated:: 4.2 + + Passing ``Value("null")`` to express JSON ``null`` is deprecated. + .. fieldlookup:: jsonfield.key Key, index, and path transforms -- cgit v1.3