17

在我的模型定义中,我有

from django.contrib.postgres.fields import JSONField
.....
.......
.........

media_data=JSONField(default=dict)

我创建了一个默认管理员

当我尝试在不触及该字段的情况下进行保存时,出现this field is required错误。

字段是必需的

它看起来像一个表单验证问题,因为我可以毫无问题地以编程方式从代码中保存模型实例。

为什么会这样?
我错过了什么傻事吗?

4

6 回答 6

23
  1. 发生了什么。深入研究源代码时。我们可以看到以下调用堆栈:
    1) form.is_valid() 
       ->form.full_clean()
        -->form._clean_fields()
         ---> self.cleand_data[name] = field.clean(value)
    2) field.clean(value)
        -> self.to_python(value)
        -> self.validate(value)

查看源代码,你可以发现,主要是因为empty_values检查。

# These values, if given to validate(), will trigger the self.required check.
EMPTY_VALUES = (None, '', [], (), {})

如您所见,空字典{}作为 JSONField 的空值。所以它会引发错误。

  1. 我们能做些什么?解决方案是自定义 models.JSONField 和 forms.JSONField 如下所示。

表格.py

from django.contrib.postgres import forms

class MyJSONField(forms.JSONField):
    empty_values = [None, "", [], ()]

数据库/字段.py

class MyJSONField(JSONField):
    def formfield(self, **kwargs):
        from ..forms import MyJSONField

        return super().formfield(**{"form_class": MyJSONField, **kwargs})
于 2019-05-23T09:07:36.300 回答
3

我遇到了同样的问题。我是如何解决的?为了绕过排除{}为有效 json 的验证过程,我同时添加了blank=Truenull=True. 例如:models.JSONField(blank=True, null=True, default=dict)

于 2021-02-24T13:58:10.600 回答
1

根据您的要求,考虑使用空白和/或空值。

media_data=JSONField(blank=True, null=True)

于 2019-03-13T16:58:21.467 回答
1

这最近给我带来了问题,尽管使用django-mysql而不是 postgres 并且在自定义ModelForm而不是管理界面中。

我最终覆盖了我的模型的save()方法:

from django_mysql.models import JSONField

class yourModel(model):
    media_data=JSONField(default=dict, blank=True)

    def clean(self, *args, **kwargs):
        if self.media_data is None:
            self.media_data = "{}"

    def save(self, *args, **kwargs):
        self.clean()
        super().save(*args, **kwargs)
于 2019-05-13T22:24:38.143 回答
0

我以前有类似的问题。在您的表单字段中添加required=False将解决问题。

class YourForm(forms.ModelForm):
    media_data = SimpleArrayField(JSONField(), required=False, widget=forms.Textarea, delimiter='|')
于 2020-03-02T06:58:14.507 回答
0

我有同样的问题,同样我创建了一个新的基于字段的类,但我没有使用表单和模型字段,而是创建了一个在实例化后调整表单字段的内部结构的类。

class CustomJSONField(JSONField):
empty_values = [None, '', [], ()]

def formfield(self, **kwargs):
    result = super().formfield(**kwargs)
    result.empty_values = self.empty_values
    return result
于 2021-12-30T05:27:28.663 回答