Opened 8 years ago

Closed 8 years ago

Last modified 6 years ago

#26482 closed New feature (wontfix)

pretty-print json in JSONField form field

Reported by: David Szotten Owned by:
Component: contrib.postgres Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Makes manual editing nicer

(json.dumps with indent)

Change History (6)

comment:1 by Tim Graham, 8 years ago

I'm not convinced this belongs in the form field. I think such logic belongs in a custom widget.

comment:2 by David Szotten, 8 years ago

ah, that's a good suggestion

comment:3 by David Szotten, 8 years ago

that solves my problem so happy to close, unless you think such a widget would make sense to include? (maybe to niche)

comment:4 by Tim Graham, 8 years ago

Resolution: wontfix
Status: newclosed

I agree.

comment:5 by Tim Graham, 8 years ago

Summary: pretty-print json in form fieldpretty-print json in JSONField form field

comment:6 by minusf, 6 years ago

I would normally agree with a custom widget approach, however json is special.
In my understanding a custom widget would have to munge through the vanilla unindented
json.dumps() value returned by contrib.postgres.forms.JSONField.prepare_value().

django/contrib/postgres/forms/jsonb.py:

    def prepare_value(self, value):
        if isinstance(value, InvalidJSONInput):
            return value
        return json.dumps(value)

Probably meaning an ugly hack of json.loads() then json.dumps() round trip inside the custom widget...

For my use cases a simple json.dumps(value, indent=2) would already make
a huge difference in readability, no custom widget needed and problem solved.
Overriding that however is a mess...

models.py:

from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.forms import JSONField as JSONFormField
from django.core.serializers.json import DjangoJSONEncoder


# XXX not exported from postgres.forms :/
class InvalidJSONInput(str):
    pass


# XXX JSONFormField would be a better name for forms.JSONField  :/
class IndentedJSONFormField(JSONFormField):

    def prepare_value(self, value):
        if isinstance(value, InvalidJSONInput):
            return value
        return json.dumps(value, indent=2)


class IndentedJSONField(JSONField):

    def formfield(self, **kwargs):
        return super().formfield(**{
            'form_class': IndentedJSONFormField,
            **kwargs,
        })


class Data(models.Model):
    data = IndentedJSONField(encoder=DjangoJSONEncoder, default=dict)
Note: See TracTickets for help on using tickets.
Back to Top