Django | admin 後臺美化處理 JSONField

1 簡單描述

在某些業務需求下,對於模型的某些字段,使用 JSONField 適配業務,可是這種字段在 django admin 下顯示以及修改不是很直觀和方便,因此這裏動了念頭,美化處理下 JSONFieldjavascript

環境以下:

  • python 3.5.2css

  • django 1.11.1html

  • postgresql 9.5.2java

2 步驟以及代碼示例說明

好比建立了一個模型python

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

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

class Book(models.Model):
    """book model"""
    name = models.CharField('書籍名稱', max_length=40, blank=True, default='')
    extra_data = JSONField('擴展數據', default={})
    create_time = models.DateTimeField('建立時間', auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '書籍'
        verbose_name_plural = '書籍'

這裏 extra_data 使用了 JSONField,若是不作任何處理,django admin 顯示的樣式以下:
圖片描述git

這種顯示,查看,修改,搜索相對來講,不是很方便,後面就打算使用 jsoneditor 處理下,處理後的結果以下:圖片描述github

2.1 步驟

2.1.1 自定義 widget

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

import json

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


class JsonEditorWidget(Widget):
    """
    在 django  admin 後臺中使用  jsoneditor 處理 JSONField

    TODO:有待改進, 這裏使用 % 格式化,使用 format 會拋出 KeyError 異常
    """

    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 在 admin.py 中引用

核心使用 formfield_overrides 設置sql

# -*- 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']

就此 over,運行本地服務,就能夠看到美化後的界面django

2.3 項目倉庫

例子可參考 示例代碼json

3 參考文章

相關文章
相關標籤/搜索