diff options
Diffstat (limited to 'django/db/models/fields/json.py')
| -rw-r--r-- | django/db/models/fields/json.py | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py index 8d743c436a..188fcf520c 100644 --- a/django/db/models/fields/json.py +++ b/django/db/models/fields/json.py @@ -99,18 +99,23 @@ class JSONField(CheckFieldDefaultMixin, Field): def get_db_prep_value(self, value, connection, prepared=False): if not prepared: value = self.get_prep_value(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) def get_db_prep_save(self, value, connection): + # This slightly involved logic is to allow for `None` to be used to + # store SQL `NULL` while `Value(None, JSONField())` can be used to + # store JSON `null` while preventing compilable `as_sql` values from + # making their way to `get_db_prep_value`, which is what the `super()` + # implementation does. if value is None: return value - return self.get_db_prep_value(value, connection) + if ( + isinstance(value, expressions.Value) + and value.value is None + and isinstance(value.output_field, JSONField) + ): + value = None + return super().get_db_prep_save(value, connection) def get_transform(self, name): transform = super().get_transform(name) |
