Django Admin:JSONField默认为空dict不会保存在admin中

时间:2019-03-13 16:47:30

标签: python django django-models django-admin django-jsonfield

在我定义的模型中

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

media_data=JSONField(default=dict)

我创建了默认管理员

当我尝试保存而不接触该字段时,出现this field is required错误。

field is required

这看起来像是表单验证问题,因为我可以以编程方式从代码中保存模型实例而不会出现问题。

为什么会这样?
我错过了一些愚蠢的事情吗?

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

这最近为我带来了问题,尽管使用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)

答案 3 :(得分:0)

  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. 我们该怎么办? 解决方案是自定义model.JSONField和form.JSONField,如下所示。

forms.py

from django.contrib.postgres import forms

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

db / fields.py

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

        return super().formfield(**{"form_class": MyJSONField, **kwargs})

答案 4 :(得分:0)

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

class YourForm(forms.ModelForm):
    media_data = SimpleArrayField(JSONField(), required=False, widget=forms.Textarea, delimiter='|')