Django Admin: JSONField default empty dict wont save in admin

前端 未结 4 1698
一向
一向 2021-02-19 11:42

in my model defn i have

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

media_data=JSONField(default=dict)

I crea

相关标签:
4条回答
  • 2021-02-19 12:01
    1. What happening. when dive into the source code. we can see the following call stack:
        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)
    

    when look into the source code ,you can find that,it's mainly because the empty_values check.

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

    as you can see the empty dict {} is as an empty value for JSONField. so it will raise Error.

    1. What can we do? the Solution would be to customize the models.JSONField and forms.JSONField like below.

    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})
    
    0 讨论(0)
  • 2021-02-19 12:05

    Depending on your requirements, consider to use blank and/or null.

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

    0 讨论(0)
  • 2021-02-19 12:08

    This caused problems for me recently, though with django-mysql rather than postgres and in a custom ModelForm rather than the admin interface.

    I ended up overriding my model's save() method:

    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)
    
    0 讨论(0)
  • 2021-02-19 12:08

    i have similar problem previously. adding required=False in your form field will solve the problem.

    class YourForm(forms.ModelForm):
        media_data = SimpleArrayField(JSONField(), required=False, widget=forms.Textarea, delimiter='|')
    
    0 讨论(0)
提交回复
热议问题