Search code examples
flaskflask-admin

flask-admin: prettify json fields


I really love the CRUD functionality of flask-admin. Unfortunately I have not yet found a way to make json DB fields more readable.

JSON fields are displayed in the list view (and also in the edit view) as strings of text.

Can anybody give me any pointers where to start to prettify the list view (and later the edit view)?


Solution

  • You can use column_formatters to customize the looks of your field in the list view:

    import json
    from flask_admin.contrib.sqla.view import ModelView
    from jinja2 import Markup
    
    def json_formatter(view, context, model, name):
        value = getattr(model, name)
        json_value = json.dumps(value, ensure_ascii=False, indent=2)
        return Markup('<pre>{}</pre>'.format(json_value))
    
    class MyView(ModelView):
        column_formatters = {
            'my_json_field': json_formatter,
        }
    

    Or you can use column_type_formatters to apply this style to all dictionary fields in your view:

    import json
    from flask_admin.model import typefmt
    from flask_admin.contrib.sqla.view import ModelView
    from jinja2 import Markup
    
    def json_formatter(view, value):
        json_value = json.dumps(value, ensure_ascii=False, indent=2)
        return Markup('<pre>{}</pre>'.format(json_value))
    
    MY_FORMATTERS = typefmt.BASE_FORMATTERS.copy()
    MY_FORMATTERS[dict] = json_formatter
    
    class MyView(ModelView):
        column_type_formatters = MY_FORMATTERS
    

    There are several other examples of flask_admin formatters usage on the Stack Overflow but it wont hurt to have one JSON-specific.

    flask_admin.form.fields.JSONField can be overriden to show pretty values in the input. form_overrides attribute is used for it:

    from flask_admin.contrib.sqla.view import ModelView
    from flask_admin.form import fields
    
    class JSONField(fields.JSONField):
        def _value(self):
            if self.raw_data:
                return self.raw_data[0]
            elif self.data:
                return json.dumps(self.data, ensure_ascii=False, indent=2)
            else:
                return ''
    
    class MyView(ModelView):
        form_overrides = {
            'my_field': JSONField,
        }