Brainstorm's snippets (1/234)

  Json prettified fields in Django admin

To render a JSONfield as colored and formatted text in a Django change-view, add a readonly field as follows:

@admin.register(DeviceTestTask)
class DeviceTestTaskAdmin(TaskAdmin):

    exclude = ('program_steps', )

    readonly_fields = [..., 'program_steps_prettified', ]

    def program_steps_prettified(self, obj):
        return json_prettify(obj.program_steps)

where json_prettify() is a helper function responsible to format JSON data using Pygments:

file admin_ex.json_prettify.py

import json
from django.utils.safestring import mark_safe
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import HtmlFormatter


def json_prettify_styles():
    """
    Used to generate Pygment styles (to be included in a .CSS file) as follows:
        print(json_prettify_styles())
    """
    formatter = HtmlFormatter(style='colorful')
    return formatter.get_style_defs()


def json_prettify(json_data):
    """
    Adapted from:
    https://www.pydanny.com/pretty-formatting-json-django-admin.html
    """

    # Get the Pygments formatter
    formatter = HtmlFormatter(style='colorful')

    # Highlight the data
    json_text = highlight(
        json.dumps(json_data, sort_keys=True, indent=2),
        JsonLexer(),
        formatter
    )

    # # remove leading and trailing brances
    # json_text = json_text \
    #     .replace('<span class="p">{</span>\n', '') \
    #     .replace('<span class="p">}</span>\n', '')

    # Get the stylesheet
    #style = "<style>" + formatter.get_style_defs() + "</style>"
    style = ''

    # Safe the output
    return mark_safe(style + json_text)

Suitable styles can be produced with:

print(json_prettify_styles())

and included in a CSS file; for example:

/*
 *  Pygment styles
 *
 *  Generated by 'gui.utils.json_prettify_styles()'
 */

.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #FF0000; background-color: #FFAAAA } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */

References: