首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django JSONField未收到已清理的数据

Django JSONField未收到已清理的数据
EN

Stack Overflow用户
提问于 2019-02-12 15:30:02
回答 1查看 609关注 0票数 0

我有一个非常简单的模型,其中包含一个JSONField

代码语言:javascript
复制
class Thing(models.Model):
    title = models.CharField(max_length=1024)
    text = JSONField(default=dict)

我已经创建了一个自定义小部件,它允许输入键值对:

代码语言:javascript
复制
class JsonWidget(forms.widgets.Widget):
    template_name = 'json_widget.html'

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        data = json.loads(value)
        if not data:
            data = JSON_DEFAULT
        context['data'] = data.items()
        return context

    def value_from_datadict(self, data, files, name):
        keys = data.getlist('json-key')
        values = data.getlist('json-value')
        json_data = {k: v for k, v in zip(keys, values)}
        return json_data

我将小部件返回的dict强制转换为表单上字段的clean函数中的字符串:

代码语言:javascript
复制
class ThingForm(forms.ModelForm):

    class Meta:
        model = Thing
        fields = ['title', 'text']
        widgets = {
            'text': JsonWidget(),
        }

    def clean_text(self):
        text = self.cleaned_data.get('text')
        return json.dumps(text)

我已经检查过JsonWidget.value_from_datadict (dict)和ThingForm.clean_text (str)的输出是预期的类型。但是当对象去保存时,它会抛出一个异常:

代码语言:javascript
复制
TypeError: the JSON object must be str, bytes or bytearray, not 'dict'

这是我第一次为Django 1.11构建自定义小部件,这里有什么明显的遗漏吗?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-02-13 11:42:51

这是一个棘手的问题,但我最终将问题追溯到了Instance construction fails on form data check

虽然JSONField在模型上称为text,但在ModelForm上没有匹配的字段。相反,键/值对被小部件的value_from_datadict编译并转换为dict。但是,只有当表单的POST数据中存在字段名称时,cleaned_data值才会保存回实例。这导致小部件抛出错误,因为text不能为空,并且在表单重新呈现期间引发了TypeError异常。

解决方法是向字段添加一个名为text的隐藏输入,并仅使用它在实例化过程中绕过字段名检查。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54644857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档