diff options
Diffstat (limited to 'django/db/models/fields')
| -rw-r--r-- | django/db/models/fields/__init__.py | 4 | ||||
| -rw-r--r-- | django/db/models/fields/json.py | 31 |
2 files changed, 33 insertions, 2 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 2a98396cad..cd995de80f 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -921,6 +921,8 @@ class Field(RegisterLookupMixin): def get_db_prep_save(self, value, connection): """Return field's value prepared for saving into a database.""" + if hasattr(value, "as_sql"): + return value return self.get_db_prep_value(value, connection=connection, prepared=False) def has_default(self): @@ -1715,6 +1717,8 @@ class DecimalField(Field): def get_db_prep_value(self, value, connection, prepared=False): if not prepared: value = self.get_prep_value(value) + if hasattr(value, "as_sql"): + return value return connection.ops.adapt_decimalfield_value( value, self.max_digits, self.decimal_places ) diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py index c0242bd7be..eb2d35f100 100644 --- a/django/db/models/fields/json.py +++ b/django/db/models/fields/json.py @@ -1,9 +1,10 @@ import json +import warnings from django import forms from django.core import checks, exceptions from django.db import NotSupportedError, connections, router -from django.db.models import lookups +from django.db.models import expressions, lookups from django.db.models.constants import LOOKUP_SEP from django.db.models.fields import TextField from django.db.models.lookups import ( @@ -11,6 +12,7 @@ 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 @@ -97,7 +99,32 @@ class JSONField(CheckFieldDefaultMixin, Field): return "JSONField" def get_db_prep_value(self, value, connection, prepared=False): - if hasattr(value, "as_sql"): + # 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 + elif hasattr(value, "as_sql"): return value return connection.ops.adapt_json_value(value, self.encoder) |
