Repository: django/django
File: django/db/models/fields/json.py (Python)

Code before:
    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        try:
            json.dumps(value, cls=self.encoder)
        except TypeError:
            raise exceptions.ValidationError(
                self.error_messages["invalid"],
                code="invalid",
                params={"value": value},
            )

    def value_to_string(self, obj):
        return self.value_from_object(obj)

    def formfield(self, **kwargs):
        return super().formfield(
            **{
                "form_class": forms.JSONField,
                "encoder": self.encoder,
                "decoder": self.decoder,
                **kwargs,
            }
        )


class JSONNull(expressions.Expression):
    """Represent JSON `null` primitive."""

    allowed_default = True

    def __init__(self):
        super().__init__(output_field=JSONField())

    def __repr__(self):
        return f"{self.__class__.__name__}()"

    def as_sql(self, compiler, connection):
        value = self.output_field.get_db_prep_value(None, connection)
        return "%s", (value,)

    def as_mysql(self, compiler, connection):
        sql, params = self.as_sql(compiler, connection)
        sql = "JSON_EXTRACT(%s, '$')"
        return sql, params


class DataContains(FieldGetDbPrepValueMixin, PostgresOperatorLookup):
    lookup_name = "contains"
    postgres_operator = "@>"

    def as_sql(self, compiler, connection):

Review comment (suggestion):
@charettes can you advise on why we wouldn't subclass `Value`?

It makes me wonder about auditing all the places we do `isinstance(..., Value)`. This site seems like something we'd need to teach about `JSONNull`:

https://github.com/django/django/blob/be581ff473e8ade6365975db2df602f295a4cb4b/django/db/backends/sqlite3/schema.py#L321-L323

Code after:
    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        try:
            json.dumps(value, cls=self.encoder)
        except TypeError:
            raise exceptions.ValidationError(
                self.error_messages["invalid"],
                code="invalid",
                params={"value": value},
            )

    def value_to_string(self, obj):
        return self.value_from_object(obj)

    def formfield(self, **kwargs):
        return super().formfield(
            **{
                "form_class": forms.JSONField,
                "encoder": self.encoder,
                "decoder": self.decoder,
                **kwargs,
            }
        )


class JSONNull(expressions.Value):
    """Represent JSON `null` primitive."""

    def __init__(self):
        super().__init__(None, output_field=JSONField())

    def __repr__(self):
        return f"{self.__class__.__name__}()"

    def as_sql(self, compiler, connection):
        value = self.output_field.get_db_prep_value(self.value, connection)
        if value is None:
            value = "null"
        return "%s", (value,)

    def as_mysql(self, compiler, connection):
        sql, params = self.as_sql(compiler, connection)
        sql = "JSON_EXTRACT(%s, '$')"
        return sql, params


class DataContains(FieldGetDbPrepValueMixin, PostgresOperatorLookup):
    lookup_name = "contains"
    postgres_operator = "@>"

    def as_sql(self, compiler, connection):