Django | admin background beautification processing jsonfield

Time:2020-10-10

1 brief description

Under certain business requirements, for some fields of the model, theJSONFieldAdapt to the service, but this field is in thedjango adminUnder the display and modification is not very intuitive and convenient, so here moved the idea, beautify processingJSONField

The environment is as follows:

  • python 3.5.2

  • django 1.11.1

  • postgresql 9.5.2

2 steps and code examples

For example, we created a model

# -*- coding: utf-8 -*-

from django.db import models
from django.contrib.postgres.fields import JSONField

class Book(models.Model):
    """book model"""
    name =  models.CharField ('book name', Max_ length=40, blank=True, default='')
    extra_ Data = jsonfield ('Extended data ', default = {})
    create_ time =  models.DateTimeField ('creation time', auto_ now_ add=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_ Name: 'book'
        verbose_ name_ Plural: 'books'

hereextra_dataUsedJSONFieldIf nothing is done, the Django admin display style is as follows:
Django | admin background beautification processing jsonfield

This kind of display, view, modify, search, relatively speaking, is not very convenient, after the plan to usejsoneditorThe results are as follows:Django | admin background beautification processing jsonfield

2.1 steps

2.1.1 custom widget

# -*- coding: utf-8 -*-

import json

from django.forms import Widget
from django.utils.safestring import mark_safe


class JsonEditorWidget(Widget):
    """
    Using jsoneeditor to process jsonfield in Django admin background

    Todo: it needs to be improved. The% format is used here, and keyerror exception will be thrown if format is used
    """

    html_template = """
    <div id='%(name)s_editor_holder' style='padding-left:170px'></div>
    <textarea hidden readonly class="vLargeTextField" cols="40" id="id_%(name)s" name="%(name)s" rows="20">%(value)s</textarea>

    <script type="text/javascript">
        var element = document.getElementById('%(name)s_editor_holder');
        var json_value = %(value)s;

        var %(name)s_editor = new JSONEditor(element, {
            onChange: function() {
                var textarea = document.getElementById('id_%(name)s');
                var json_changed = JSON.stringify(%(name)s_editor.get()['Object']);
                textarea.value = json_changed;
            }
        });

        %(name)s_editor.set({"Object": json_value})
        %(name)s_editor.expandAll()
    </script>
    """

    def __init__(self, attrs=None):
        super(JsonEditorWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if isinstance(value, str):
            value = json.loads(value)

        result = self.html_template % {'name': name, 'value': json.dumps(value),}
        return mark_safe(result)

2.1.2 in admin.py Quoted in

Core useformfield_overridesset up

# -*- coding: utf-8 -*-

from django.contrib import admin
from django.contrib.postgres.fields import JSONField

from djexample.djtools import widgets
from . import models


class CommonAdminMixin(admin.ModelAdmin):
    """Common Admin Mixin"""
    list_max_show_all = 20
    list_per_page = 20

    formfield_overrides = {
        JSONField: {'widget': widgets.JsonEditorWidget}
    }

    class Media:
        from django.conf import settings
        static_url = getattr(settings, 'STATIC_URL')

        css = {
            'all': (static_url + 'jsoneditor.min.css', )
        }
        js = (static_url + 'jsoneditor-minimalist.min.js', )


@admin.register(models.Book)
class BookAdmin(CommonAdminMixin):
    """docstring for BookAdmin"""
    list_display = ['id', 'name']

In this case, run the local service and you can see the beautified interface

2.3 project warehouse

Examples can be referred toSample code

3 reference articles