mirror of https://github.com/django/django.git
Refs #12990 -- Removed django.contrib.postgres.fields.JSONField per deprecation timeline.
This commit is contained in:
parent
98ae3925e5
commit
7cb5712edc
|
@ -11,14 +11,13 @@ __all__ = ['JSONField']
|
||||||
|
|
||||||
|
|
||||||
class JSONField(BuiltinJSONField):
|
class JSONField(BuiltinJSONField):
|
||||||
system_check_deprecated_details = {
|
system_check_removed_details = {
|
||||||
'msg': (
|
'msg': (
|
||||||
'django.contrib.postgres.fields.JSONField is deprecated. Support '
|
'django.contrib.postgres.fields.JSONField is removed except for '
|
||||||
'for it (except in historical migrations) will be removed in '
|
'support in historical migrations.'
|
||||||
'Django 4.0.'
|
|
||||||
),
|
),
|
||||||
'hint': 'Use django.db.models.JSONField instead.',
|
'hint': 'Use django.db.models.JSONField instead.',
|
||||||
'id': 'fields.W904',
|
'id': 'fields.E904',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,9 @@ Model fields
|
||||||
historical migrations.
|
historical migrations.
|
||||||
* **fields.W904**: ``django.contrib.postgres.fields.JSONField`` is deprecated.
|
* **fields.W904**: ``django.contrib.postgres.fields.JSONField`` is deprecated.
|
||||||
Support for it (except in historical migrations) will be removed in Django
|
Support for it (except in historical migrations) will be removed in Django
|
||||||
4.0.
|
4.0. *This check appeared in Django 3.1 and 3.2*.
|
||||||
|
* **fields.E904**: ``django.contrib.postgres.fields.JSONField`` is removed
|
||||||
|
except for support in historical migrations.
|
||||||
|
|
||||||
File fields
|
File fields
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
|
@ -482,59 +482,6 @@ using in conjunction with lookups on
|
||||||
>>> Dog.objects.filter(data__values__contains=['collie'])
|
>>> Dog.objects.filter(data__values__contains=['collie'])
|
||||||
<QuerySet [<Dog: Meg>]>
|
<QuerySet [<Dog: Meg>]>
|
||||||
|
|
||||||
``JSONField``
|
|
||||||
=============
|
|
||||||
|
|
||||||
.. class:: JSONField(encoder=None, **options)
|
|
||||||
|
|
||||||
A field for storing JSON encoded data. In Python the data is represented in
|
|
||||||
its Python native format: dictionaries, lists, strings, numbers, booleans
|
|
||||||
and ``None``.
|
|
||||||
|
|
||||||
.. attribute:: encoder
|
|
||||||
|
|
||||||
An optional JSON-encoding class to serialize data types not supported
|
|
||||||
by the standard JSON serializer (``datetime``, ``uuid``, etc.). For
|
|
||||||
example, you can use the
|
|
||||||
:class:`~django.core.serializers.json.DjangoJSONEncoder` class or any
|
|
||||||
other :py:class:`json.JSONEncoder` subclass.
|
|
||||||
|
|
||||||
When the value is retrieved from the database, it will be in the format
|
|
||||||
chosen by the custom encoder (most often a string), so you'll need to
|
|
||||||
take extra steps to convert the value back to the initial data type
|
|
||||||
(:meth:`Model.from_db() <django.db.models.Model.from_db>` and
|
|
||||||
:meth:`Field.from_db_value() <django.db.models.Field.from_db_value>`
|
|
||||||
are two possible hooks for that purpose). Your deserialization may need
|
|
||||||
to account for the fact that you can't be certain of the input type.
|
|
||||||
For example, you run the risk of returning a ``datetime`` that was
|
|
||||||
actually a string that just happened to be in the same format chosen
|
|
||||||
for ``datetime``\s.
|
|
||||||
|
|
||||||
If you give the field a :attr:`~django.db.models.Field.default`, ensure
|
|
||||||
it's a callable such as ``dict`` (for an empty default) or a callable that
|
|
||||||
returns a dict (such as a function). Incorrectly using ``default={}``
|
|
||||||
creates a mutable default that is shared between all instances of
|
|
||||||
``JSONField``.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
PostgreSQL has two native JSON based data types: ``json`` and ``jsonb``.
|
|
||||||
The main difference between them is how they are stored and how they can be
|
|
||||||
queried. PostgreSQL's ``json`` field is stored as the original string
|
|
||||||
representation of the JSON and must be decoded on the fly when queried
|
|
||||||
based on keys. The ``jsonb`` field is stored based on the actual structure
|
|
||||||
of the JSON which allows indexing. The trade-off is a small additional cost
|
|
||||||
on writing to the ``jsonb`` field. ``JSONField`` uses ``jsonb``.
|
|
||||||
|
|
||||||
.. deprecated:: 3.1
|
|
||||||
|
|
||||||
Use :class:`django.db.models.JSONField` instead.
|
|
||||||
|
|
||||||
Querying ``JSONField``
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
See :ref:`querying-jsonfield` for details.
|
|
||||||
|
|
||||||
.. _range-fields:
|
.. _range-fields:
|
||||||
|
|
||||||
Range Fields
|
Range Fields
|
||||||
|
|
|
@ -41,7 +41,7 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
====================================================================================================
|
====================================================================================================
|
||||||
|
|
||||||
:lookup:`Key and index lookups <jsonfield.key>` for
|
:lookup:`Key and index lookups <jsonfield.key>` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and :lookup:`key lookups
|
``django.contrib.postgres.fields.JSONField`` and :lookup:`key lookups
|
||||||
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
|
@ -10,6 +10,6 @@ Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* Fixed crash of ``KeyTransform()`` for
|
* Fixed crash of ``KeyTransform()`` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and
|
``django.contrib.postgres.fields.JSONField`` and
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
||||||
expressions with params (:ticket:`30672`).
|
expressions with params (:ticket:`30672`).
|
||||||
|
|
|
@ -10,5 +10,5 @@ Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* Fixed a crash when filtering with a ``Subquery()`` annotation of a queryset
|
* Fixed a crash when filtering with a ``Subquery()`` annotation of a queryset
|
||||||
containing :class:`~django.contrib.postgres.fields.JSONField` or
|
containing ``django.contrib.postgres.fields.JSONField`` or
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
||||||
|
|
|
@ -11,5 +11,5 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
||||||
``has_keys``, or ``has_any_keys`` lookup on
|
``has_keys``, or ``has_any_keys`` lookup on
|
||||||
:class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
|
``django.contrib.postgres.fields.JSONField``, if the right or left hand
|
||||||
side of an expression is a key transform (:ticket:`30826`).
|
side of an expression is a key transform (:ticket:`30826`).
|
||||||
|
|
|
@ -211,7 +211,7 @@ Minor features
|
||||||
:class:`~django.contrib.postgres.indexes.BrinIndex` classes allow
|
:class:`~django.contrib.postgres.indexes.BrinIndex` classes allow
|
||||||
creating ``GIN`` and ``BRIN`` indexes in the database.
|
creating ``GIN`` and ``BRIN`` indexes in the database.
|
||||||
|
|
||||||
* :class:`~django.contrib.postgres.fields.JSONField` accepts a new ``encoder``
|
* ``django.contrib.postgres.fields.JSONField`` accepts a new ``encoder``
|
||||||
parameter to specify a custom class to encode data types not supported by the
|
parameter to specify a custom class to encode data types not supported by the
|
||||||
standard encoder.
|
standard encoder.
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ Minor features
|
||||||
* Added support for the :lookup:`rangefield.contained_by` lookup for some built
|
* Added support for the :lookup:`rangefield.contained_by` lookup for some built
|
||||||
in fields which correspond to the range fields.
|
in fields which correspond to the range fields.
|
||||||
|
|
||||||
* Added :class:`~django.contrib.postgres.fields.JSONField`.
|
* Added ``django.contrib.postgres.fields.JSONField``.
|
||||||
|
|
||||||
* Added :doc:`/ref/contrib/postgres/aggregates`.
|
* Added :doc:`/ref/contrib/postgres/aggregates`.
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
====================================================================================================
|
====================================================================================================
|
||||||
|
|
||||||
:lookup:`Key and index lookups <jsonfield.key>` for
|
:lookup:`Key and index lookups <jsonfield.key>` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and :lookup:`key lookups
|
``django.contrib.postgres.fields.JSONField`` and :lookup:`key lookups
|
||||||
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
|
@ -10,6 +10,6 @@ Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* Fixed crash of ``KeyTransform()`` for
|
* Fixed crash of ``KeyTransform()`` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and
|
``django.contrib.postgres.fields.JSONField`` and
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
||||||
expressions with params (:ticket:`30672`).
|
expressions with params (:ticket:`30672`).
|
||||||
|
|
|
@ -10,5 +10,5 @@ Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* Fixed a crash when filtering with a ``Subquery()`` annotation of a queryset
|
* Fixed a crash when filtering with a ``Subquery()`` annotation of a queryset
|
||||||
containing :class:`~django.contrib.postgres.fields.JSONField` or
|
containing ``django.contrib.postgres.fields.JSONField`` or
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
||||||
|
|
|
@ -11,5 +11,5 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
||||||
``has_keys``, or ``has_any_keys`` lookup on
|
``has_keys``, or ``has_any_keys`` lookup on
|
||||||
:class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
|
``django.contrib.postgres.fields.JSONField``, if the right or left hand
|
||||||
side of an expression is a key transform (:ticket:`30826`).
|
side of an expression is a key transform (:ticket:`30826`).
|
||||||
|
|
|
@ -373,7 +373,7 @@ Miscellaneous
|
||||||
* Since migrations are now loaded from ``.pyc`` files, you might need to delete
|
* Since migrations are now loaded from ``.pyc`` files, you might need to delete
|
||||||
them if you're working in a mixed Python 2 and Python 3 environment.
|
them if you're working in a mixed Python 2 and Python 3 environment.
|
||||||
|
|
||||||
* Using ``None`` as a :class:`~django.contrib.postgres.fields.JSONField` lookup
|
* Using ``None`` as a ``django.contrib.postgres.fields.JSONField`` lookup
|
||||||
value now matches objects that have the specified key and a null value rather
|
value now matches objects that have the specified key and a null value rather
|
||||||
than objects that don't have the key.
|
than objects that don't have the key.
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
====================================================================================================
|
====================================================================================================
|
||||||
|
|
||||||
:lookup:`Key and index lookups <jsonfield.key>` for
|
:lookup:`Key and index lookups <jsonfield.key>` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and :lookup:`key lookups
|
``django.contrib.postgres.fields.JSONField`` and :lookup:`key lookups
|
||||||
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
|
@ -14,7 +14,7 @@ Bugfixes
|
||||||
(:ticket:`30673`).
|
(:ticket:`30673`).
|
||||||
|
|
||||||
* Fixed crash of ``KeyTransform()`` for
|
* Fixed crash of ``KeyTransform()`` for
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` and
|
``django.contrib.postgres.fields.JSONField`` and
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
:class:`~django.contrib.postgres.fields.HStoreField` when using on
|
||||||
expressions with params (:ticket:`30672`).
|
expressions with params (:ticket:`30672`).
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,5 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a regression in Django 2.2.4 that caused a crash when filtering with a
|
* Fixed a regression in Django 2.2.4 that caused a crash when filtering with a
|
||||||
``Subquery()`` annotation of a queryset containing
|
``Subquery()`` annotation of a queryset containing
|
||||||
:class:`~django.contrib.postgres.fields.JSONField` or
|
``django.contrib.postgres.fields.JSONField`` or
|
||||||
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
:class:`~django.contrib.postgres.fields.HStoreField` (:ticket:`30769`).
|
||||||
|
|
|
@ -11,7 +11,7 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
* Fixed a crash when using a ``contains``, ``contained_by``, ``has_key``,
|
||||||
``has_keys``, or ``has_any_keys`` lookup on
|
``has_keys``, or ``has_any_keys`` lookup on
|
||||||
:class:`~django.contrib.postgres.fields.JSONField`, if the right or left hand
|
``django.contrib.postgres.fields.JSONField``, if the right or left hand
|
||||||
side of an expression is a key transform (:ticket:`30826`).
|
side of an expression is a key transform (:ticket:`30826`).
|
||||||
|
|
||||||
* Prevented :option:`migrate --plan` from showing that ``RunPython`` operations
|
* Prevented :option:`migrate --plan` from showing that ``RunPython`` operations
|
||||||
|
|
|
@ -313,3 +313,6 @@ to remove usage of these features.
|
||||||
historical migrations.
|
historical migrations.
|
||||||
|
|
||||||
* ``django.conf.urls.url()`` is removed.
|
* ``django.conf.urls.url()`` is removed.
|
||||||
|
|
||||||
|
* The ``django.contrib.postgres.fields.JSONField`` model field is removed,
|
||||||
|
except for support in historical migrations.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
from unittest import skipUnless
|
||||||
|
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
from django.db import models
|
from django.db import connection, models
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import isolate_apps
|
from django.test.utils import isolate_apps
|
||||||
|
|
||||||
|
@ -52,3 +54,20 @@ class DeprecatedFieldsTests(SimpleTestCase):
|
||||||
id='fields.E903',
|
id='fields.E903',
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific SQL')
|
||||||
|
def test_postgres_jsonfield_deprecated(self):
|
||||||
|
from django.contrib.postgres.fields import JSONField
|
||||||
|
|
||||||
|
class PostgresJSONFieldModel(models.Model):
|
||||||
|
field = JSONField()
|
||||||
|
|
||||||
|
self.assertEqual(PostgresJSONFieldModel.check(), [
|
||||||
|
checks.Error(
|
||||||
|
'django.contrib.postgres.fields.JSONField is removed except '
|
||||||
|
'for support in historical migrations.',
|
||||||
|
hint='Use django.db.models.JSONField instead.',
|
||||||
|
obj=PostgresJSONFieldModel._meta.get_field('field'),
|
||||||
|
id='fields.E904',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
|
@ -1,35 +1,17 @@
|
||||||
try:
|
try:
|
||||||
from django.contrib.postgres import forms
|
from django.contrib.postgres import forms
|
||||||
from django.contrib.postgres.fields import JSONField
|
|
||||||
from django.contrib.postgres.fields.jsonb import (
|
from django.contrib.postgres.fields.jsonb import (
|
||||||
KeyTextTransform, KeyTransform,
|
KeyTextTransform, KeyTransform,
|
||||||
)
|
)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from django.core.checks import Warning as DjangoWarning
|
|
||||||
from django.utils.deprecation import RemovedInDjango40Warning
|
from django.utils.deprecation import RemovedInDjango40Warning
|
||||||
|
|
||||||
from . import PostgreSQLSimpleTestCase
|
from . import PostgreSQLSimpleTestCase
|
||||||
from .models import PostgreSQLModel
|
|
||||||
|
|
||||||
|
|
||||||
class DeprecationTests(PostgreSQLSimpleTestCase):
|
class DeprecationTests(PostgreSQLSimpleTestCase):
|
||||||
def test_model_field_deprecation_message(self):
|
|
||||||
class PostgreSQLJSONModel(PostgreSQLModel):
|
|
||||||
field = JSONField()
|
|
||||||
|
|
||||||
self.assertEqual(PostgreSQLJSONModel().check(), [
|
|
||||||
DjangoWarning(
|
|
||||||
'django.contrib.postgres.fields.JSONField is deprecated. '
|
|
||||||
'Support for it (except in historical migrations) will be '
|
|
||||||
'removed in Django 4.0.',
|
|
||||||
hint='Use django.db.models.JSONField instead.',
|
|
||||||
obj=PostgreSQLJSONModel._meta.get_field('field'),
|
|
||||||
id='fields.W904',
|
|
||||||
),
|
|
||||||
])
|
|
||||||
|
|
||||||
def test_form_field_deprecation_message(self):
|
def test_form_field_deprecation_message(self):
|
||||||
msg = (
|
msg = (
|
||||||
'django.contrib.postgres.forms.JSONField is deprecated in favor '
|
'django.contrib.postgres.forms.JSONField is deprecated in favor '
|
||||||
|
|
Loading…
Reference in New Issue