将 Django JSONField 处理为 YAML

Process Django JSONField as YAML

目前在 Django 中的 Postgres JSONField 模型字段在 CharField 表单字段中显示为普通 JSON 文本。

我想在 CharField 中将数据显示为 YAML 文本(同时在内部保持 JSON 格式)并在保存时将其转换回 JSON,例如:

yaml.dump(json.loads(value))

当前:

必要:

如何实现?

谢谢。

解决方案是将 JSONField(模型和表单)子类化,并将 json 替换为 yaml。作为单独的包装制成: https://github.com/mike-tk/django-yamlfield

from django.contrib.postgres import fields, forms
import yaml
from django.utils.translation import gettext_lazy as _

class InvalidYAMLInput(str):
    pass


class YAMLString(str):
    pass


class YAMLFormField(forms.JSONField):
    default_error_messages = {
        'invalid': _("'%(value)s' value must be valid YAML."),
    }

    def to_python(self, value):
        if self.disabled:
            return value
        if value in self.empty_values:
            return None
        elif isinstance(value, (list, dict, int, float, YAMLString)):
            return value
        try:
            converted = yaml.load(value)
        except yaml.YAMLError:
            raise forms.ValidationError(
                self.error_messages['invalid'],
                code='invalid',
                params={'value': value},
            )
        if isinstance(converted, str):
            return YAMLString(converted)
        else:
            return converted

    def bound_data(self, data, initial):
        if self.disabled:
            return initial
        try:
            return yaml.load(data)
        except yaml.YAMLError:
            return InvalidYAMLInput(data)

    def prepare_value(self, value):
        if isinstance(value, InvalidYAMLInput):
            return value
        return yaml.dump(value, default_flow_style=False)


class YAMLField(fields.JSONField):
    def formfield(self, **kwargs):
        defaults = {'form_class': YAMLFormField}
        defaults.update(kwargs)
        return super().formfield(**defaults)