django-prettyjson icon indicating copy to clipboard operation
django-prettyjson copied to clipboard

The formatting does not work on read-only fields

Open tahmidkhan opened this issue 5 years ago • 10 comments

My code setup is as follows:

models.py

class MyModel(models.Model):
    structure = JSONField(default=dict, blank=True, null=True)
    static_structure = JSONField(default=dict, blank=True, null=True, editable=False)

admin.py

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        JSONField: {'widget': PrettyJSONWidget }
    }

    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ('static_structure')
        else:
            return super(MyModelAdmin, self).get_readonly_fields(request, obj)

admin.site.register(MyModel, MyModelAdmin)

In other words, one of the JSONFields is not editable and read-only. It appears on my admin panel, but its not being affected by the widget which renders the other field as formatted JSON.

Is this by design? And is there any way to have the formatting work for read-only fields?

tahmidkhan avatar Oct 21 '18 09:10 tahmidkhan

Try making the field disabled -- see #9. I'm not sure how this interacts with editable=False though -- let me know if it works for you.

kevinmickey avatar Oct 21 '18 14:10 kevinmickey

Try making the field disabled -- see #9. I'm not sure how this interacts with editable=False though -- let me know if it works for you.

Nope, does not seem to work.

tahmidkhan avatar Oct 21 '18 14:10 tahmidkhan

What versions of Python, Django, and django-prettyjson are you using?

What combination of disabled, editable, and readonly did you try?

kevinmickey avatar Oct 21 '18 14:10 kevinmickey

Python 3.3, Django 2.1, and latest for this library. Editable is set to False in my models.

tahmidkhan avatar Oct 21 '18 14:10 tahmidkhan

These lines of code in the django source could be helpful. It sets all fields to exclude, which will likely affect the callback later on, which is what uses the formfield_overrides

mjhanke avatar Jun 11 '19 17:06 mjhanke

I can confirm that including a JSONField in readonly_fields prevents the PrettyJSONWidget from being used.

But setting the field disabled does have the desired effect: the PrettyJSONWidget is rendered but you can't edit the text-area.

This can be done by overriding ModelAdmin.get_form:

def get_form(self, *args, **kwargs):
    form = super().get_form(*args, **kwargs)
    my_json_field = form.base_fields["my_json_field"]
    my_json_field.disabled = True
    my_json_field.widget = PrettyJSONWidget(attrs={"initial": "parsed"})
    return form

Working with Django 2.2.5, django-prettyjson 0.4.1

BenVosper avatar Sep 26 '19 15:09 BenVosper

I ran into this issue too. I tried your workaround @BenVosper and while this works for a user who has elevated permissions for a model, if the user only has the "view" permission for a model then Django automatically makes all fields read-only and as such django-prettyjson does nothing and the user just sees the plain text / string version of the JSON.

@kevinmickey any thoughts on how to get django-prettyjson to work for read-only fields?

jordanmkoncz avatar Feb 16 '20 01:02 jordanmkoncz

Did any of you find a solution to easily format readonly JSONFields ?

raphodn avatar Apr 29 '21 08:04 raphodn

Add this to your admin instead of making the field read only

formfield_overrides = {
        django.db.models.JSONField: {
            'widget': django_json_widget.widgets.JSONEditorWidget(options={
                'mode': 'view',
                'modes': ['view']
            })
        },
    }

omnir95 avatar Oct 21 '21 23:10 omnir95

Since including a JSONField in readonly_fields prevents the PrettyJSONWidget from being used, instead of overriding ModelAdmin.get_formas suggested, it is possible to pass the disable parameter as an attribute for PrettyJSONWidget too:

formfield_overrides = {
    JSONField: {
        "widget": PrettyJSONWidget(
            attrs={"initial": "parsed", "disabled": True}
        )
    }
}

Working with Django 3.1.13, django-prettyjson 0.4.1

marcussilvait avatar Jan 14 '22 17:01 marcussilvait