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

Code before:
                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):
        if not connection.features.supports_json_field_contains:
            raise NotSupportedError(
                "contains lookup is not supported on this database backend."
            )
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)

Review comment (suggestion):
More subclass friendly?
```suggestion
    output_field = JSONField()
```

Code after:
                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):
        if not connection.features.supports_json_field_contains:
            raise NotSupportedError(
                "contains lookup is not supported on this database backend."
            )
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)