doableware / djongo

Django and MongoDB database connector
https://www.djongomapper.com
GNU Affero General Public License v3.0
1.86k stars 352 forks source link

Broken JSONField in admin page #622

Open pimuzzo opened 2 years ago

pimuzzo commented 2 years ago

I have a custom user model like this:

from djongo.models import JSONField

class User(AbstractUser):
    _id = ObjectIdField(primary_key=True)
    extra = JSONField(default=dict)

doesn't work on the admin page, in particular trying to make it show, results in an error in this Djongo's method because value is of type collections.OrderedDict instead of dict or list:

    def to_python(self, value):
        if not isinstance(value, (dict, list)):
            raise ValueError(
                f'Value: {value} stored in DB must be of type dict/list'
                'Did you miss any Migrations?'
            )
        return value
wuyue92tree commented 2 years ago

Maybe you can extend the JSONField like bellow

# fields.py
from djongo.models import JSONField  # type: ignore

class MyJSONField(JSONField):
    """ do eval beforce save to mongo """
    def to_python(self, value):
        try:
            value = eval(value)
        except Exception as e:
            raise ValueError(
                f'Value: {value} invalid, make sure before submit?'
            )
        return super().to_python(value)
# models.py
from djongo import models
from .fields import MyJSONField

class CollectorPool(models.Model):
    ...
    extra_data = MyJSONField(blank=True, null=True, verbose_name='extra data')
# admin.py
from jsoneditor.forms import JSONEditor
from .fields import MyJSONField

@admin.register(CollectorPool)
class CollectorPoolAdmin(admin.ModelAdmin):
    ...
    formfield_overrides = {
        MyJSONField: {'widget': JSONEditor(attrs={'style': 'width: 620px;'})}
    }

in django admin image

in mongo image

hope this helps.