Django 管理员:JSONField 默认空字典不会保存在管理员中

Django Admin: JSONField default empty dict wont save in admin

在我的模型定义中我有

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

media_data=JSONField(default=dict)

我创建了默认管理员

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

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

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

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

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

这最近给我带来了问题,尽管使用 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)
  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,如下所示。

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})

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

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

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

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

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

def formfield(self, **kwargs):
    result = super().formfield(**kwargs)
    result.empty_values = self.empty_values
    return result