JsonEditor 与 Django Admin 集成

Posted

技术标签:

【中文标题】JsonEditor 与 Django Admin 集成【英文标题】:JsonEditor integration with Django Admin 【发布时间】:2016-09-28 20:54:20 【问题描述】:

我正在努力将JSONEditor 集成到 Django 管理员中。我的模型中有一个字段使用 Postgres JSON,并且这个库中的树编辑器非常完美。

models.py

​​>
class Executable(models.Model):
    """ Simplified model for sake of the question."""

    recipe = JSONField(null=True, blank=True)

我已经取得了不错的进展(我认为)将 JSONEditor 库集成到 Django Admin 中适当的创建/编辑屏幕中。数据在加载时显示正确,但由于某种原因,当我在 JSONEditorWidget 中进行编辑时,未保存更改。我确定我需要处理一些 save 覆盖,或者我遗漏了一些明显的东西,但我真的不确定从这里去哪里。

admin.py

​​>
import json
from django import forms, utils
from django.contrib import admin

from .models import Executable


class JSONEditorWidget(forms.Widget):
    html_template = """
        <div id='%(name)s_editor_holder'></div>
        <script type="text/javascript">
                var options = 
                    "mode": "tree",
                    "search": true
                ;
                var %(name)s_editor = new JSONEditor(container, options);
                var json = %(value)s
                %(name)s_editor.set(json);
                %(name)s_editor.expandAll();

                var json = %(name)s_editor.get(json);
        </script>
        <textarea readonly class="vLargeTextField" cols="40" id="id_%(name)s" name="%(name)s" rows="2" >%(value)s</textarea>
    """
    def __init__(self, attrs=None, formats=None, defaults=None):
        self.formats = formats
        self.defaults = defaults
        super(JSONEditorWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if isinstance(value, basestring):  # Edit existing instance
            value = json.loads(value)
        result = self.html_template % 
            'name': name,
            'value': json.dumps(value)
        
        return utils.safestring.mark_safe(result)


class ExecutableForm(forms.ModelForm):
    recipe = forms.CharField(widget=JSONEditorWidget())    # Kwargs here?

    class Meta:
        model = Executable
        fields = '__all__'

    class Media:
        css = 
            'all': ('http://www.jsoneditoronline.org/app.min.css',)  # TEMP
        
        js = (
            'http://www.jsoneditoronline.org/app.min.js',   # TEMP
            )


class ExecutableAdmin(admin.ModelAdmin):
    model = Executable
    form = ExecutableForm
    fields = (('request', 'status'), 'recipe')


admin.site.register(Executable, ExecutableAdmin)

【问题讨论】:

@e4c5 该库文档齐全,可在 Github 上找到。是什么让你觉得不是?顺便说一句,我还是一个新手程序员,所以也许我错过了一些东西:) 对不起,我误会了,我之前没有使用过这个库,但是在访问该站点时,没有可见的开发人员或 github 链接 @e4c5 不用担心,链接隐藏在页脚中,我可以看到您如何得出这个结论。我更新了帖子中的链接,指向 GitHub 存储库,而不是演示站点 (github.com/josdejong/jsoneditor) 【参考方案1】:

我对 Django 1.10.2、jsoneditor#^5.5.9、Postgres 9.5 的解决方案:

models.py

from django.contrib.postgres.fields import JSONField

class Consumer(models.Model):
    data = JSONField(default=dict, db_index=True)

admin.py:

from django import forms
from django.contrib import admin
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string

from .models import Consumer


class JSONEditorWidget(forms.Widget):

    template_name = 'jsoneditor.html'

    def render(self, name, value, attrs=None):
        context = 
            'data': value,
            'name': name
        

        return mark_safe(render_to_string(self.template_name, context))


class ConsumerForm(forms.ModelForm):

    class Meta:
        model = Consumer
        fields = '__all__'
        widgets = 
            'data': JSONEditorWidget()
        

    class Media:
        css =  'all': ('jsoneditor/dist/jsoneditor.min.css',) 
        js = ('jsoneditor/dist/jsoneditor.min.js', )


class ConsumerAdmin(admin.ModelAdmin):
    list_display = ['pk']
    model = Consumer
    form = ConsumerForm

admin.site.register(Consumer, ConsumerAdmin)

jsoneditor.html:

<div id=" name _editor"></div>

<textarea cols="40" id="id_ name " name=" name " rows="10" required="" style="display: none"> data </textarea>


<script>
    console.log('jsoneditor.html');
    var container = document.getElementById(" name _editor");

    var options = 
        modes: ['code', 'tree'],
        search: true,

        onChange: function () 
            var json = editor.get();
            document.getElementById("id_ name ").value=JSON.stringify(json);
        
    ;

    var editor = new JSONEditor(container, options);
    var json =  data|safe ;
    editor.set(json);
</script>

块引用 写于StackEdit。

【讨论】:

我一直在寻找类似的东西......谢谢 对不起,但这对我来说并不完美。我不得不添加一些小的调整,尤其是。将 json 文本转换为 json var json = JSON.parse( data|safe ); 并将 onChange 重命名为 change。以下是更新的要点gist.github.com/rgupta2/761fd987254703673d83426912dc015d

以上是关于JsonEditor 与 Django Admin 集成的主要内容,如果未能解决你的问题,请参考以下文章

vue 中的 JsonEditor 组件未显示

python 管理员为Django,jsoneditor,Postgres的JSON编辑器(来自http://stackoverflow.com/a/40326235/2742038)

如何将 django-admin-bootstrapped 与 django 1.10 集成

Django 命令行工具django-admin.py与manage.py

Django admin 组件 原理分析与扩展使用 之 sites.py

django项目一:基于django2.2可重用登录与注册模块-admin后台