IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Django | admin 后台美化处理 JSONField

    kycool发表于 2017-05-11 12:10:24
    love 0

    1 简单描述

    在某些业务需求下,对于模型的某些字段,使用 JSONField 适配业务,但是这种字段在 django admin 下显示以及修改不是很直观和方便,所以这里动了念头,美化处理下 JSONField。

    环境如下:

    • python 3.5.2

    • django 1.11.1

    • postgresql 9.5.2

    2 步骤以及代码示例说明

    比如创建了一个模型

    # -*- 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 显示的样式如下:
    图片描述

    这种显示,查看,修改,搜索相对来说,不是很方便,后面就打算使用 jsoneditor 处理下,处理后的结果如下:图片描述

    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 设置

    # -*- 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,运行本地服务,就可以看到美化后的界面

    2.3 项目仓库

    例子可参考 示例代码

    3 参考文章

    • https://ariesfath.wordpress.c...



沪ICP备19023445号-2号
友情链接