in my model defn i have
from django.contrib.postgres.fields import JSONField
.....
.......
.........
media_data=JSONField(default=dict)
I created a default admin
When i attempt to save without touching the field, i get a this field is required
error.
It looks like a form validation issue because I can programatically save the model instance from code without issue.
Why is this happening?
have i missed something silly?
According to the Django documentation for JSONFieldyou should indeed use default=listbecause using default=[]would create a mutable object that is shared between all instances of your field and could lead to some objects not having an empty list as a default.
To show formatted JSON in admin page I recommend you python library django-json-widget. It is easy to use and has great features (you can edit formatted JSON). INSTALLED_APPS = ( ... 'django_json_widget', ...
If you give the field a default, ensure it’s a callable such as list (for an empty default) or a callable that returns a list (such as a function). Incorrectly using default=[] creates a mutable default that is shared between all instances of
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.
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})
I faced the same issue. How did I fix it? In order to bypass the validation process that excludes {}
as valid json, I added both blank=True
and null=True
. For example: models.JSONField(blank=True, null=True, default=dict)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With