Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Admin: JSONField default empty dict wont save in admin

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.

field is required

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?

like image 463
w-- Avatar asked Mar 13 '19 16:03

w--


People also ask

Should I use default=[] or default=list for a jsonfield in Django?

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.

How to show formatted JSON in admin page in Django?

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', ...

What happens if you give a field a default value?

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


2 Answers

  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})
like image 98
banxi1988 Avatar answered Sep 20 '22 15:09

banxi1988


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)

like image 22
Eyong Kevin Enowanyo Avatar answered Sep 21 '22 15:09

Eyong Kevin Enowanyo