【问题标题】:Process Django JSONField as YAML将 Django JSONField 处理为 YAML
【发布时间】:2018-04-08 16:23:04
【问题描述】:

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

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

yaml.dump(json.loads(value))

当前:

必填:

如何做到这一点?

谢谢。

【问题讨论】:

  • 您可以在__init__ 中将其转换为YAML,并在pre_save 信号或保存函数中转换回json(在super() 保存调用之前)
  • Ramkishore M 需要更通用的东西,添加新的字段类是可以的,没有办法在 init AFAIK 中转换
  • 如果 YAML 不是强制性的,您可以使用 django-json-widget。或者,您可以创建一个 widget,将 JSON 转换为 YAML 并返回。

标签: json django forms yaml models


【解决方案1】:

解决方案是子类化 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)

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 2016-05-30
    • 2016-07-23
    • 2016-08-07
    • 2013-01-01
    • 2020-10-09
    • 2016-11-26
    • 2018-01-18
    • 2017-04-29
    相关资源
    最近更新 更多