Я работаю над интеграцией JSONEditor в панель администратора Django. В моей модели есть одно поле, которое использует Postgres JSON, и редактор дерева в этой библиотеке идеален.
модели.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" height="20px">%(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)