Skip to content

Django admin inlines support (and js code separation from template) #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,33 @@ class JSONModelAdmin(admin.ModelAdmin):
return form
```

### Django admin inlines

JSONEditorWidget may be used also with django admin inlines,
by overriding

1) the get_formset method of the StackedInline (or TabularInline) class, and

2) the get_form method of the ModelAdmin class,

like in the example below.


```python
class RelatedJSONModelStackedInline(admin.StackedInline):
model = RelatedJSONModel
def get_formset(self, request, obj=None, **kwargs):
widgets = {
'related_data': JSONEditorWidget(RELATED_DATA_SCHEMA, False),
}
return super().get_formset(request, obj, widgets=widgets, **kwargs)

@admin.register(MyJSONModel)
class MyJSONModelAdmin(admin.ModelAdmin):
inlines = [ RelatedJSONModelStackedInline, ]
def get_form(self, request, obj=None, **kwargs):
widgets = {
'data': JSONEditorWidget(DATA_SCHEMA, collapsed=False),
}
return super().get_form(request, obj, widgets=widgets, **kwargs)
```
1 change: 1 addition & 0 deletions django_admin_json_editor/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def media(self):
'django_admin_json_editor/jquery/jquery.min.js',
'django_admin_json_editor/bootstrap/js/bootstrap.min.js',
'django_admin_json_editor/jsoneditor/jsoneditor.min.js',
'django_admin_json_editor/editor.js',
]
if self._sceditor:
css['all'].append('django_admin_json_editor/sceditor/themes/default.min.css')
Expand Down
44 changes: 44 additions & 0 deletions django_admin_json_editor/static/django_admin_json_editor/editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
var editor = {}
var $ = django.jQuery
var enable_json_editor = function(element){
var id = element.id
if (id.indexOf('__prefix__') === -1) { // activate editor only if it is not an inline template row
var textarea_id = "id_"+element.id.replace('_editor', '')
var schema = JSON.parse(element.getAttribute('data-schema'))
var data = JSON.parse(element.getAttribute('data-data'))
var options = {
theme: "bootstrap3",
iconlib: "fontawesome4",
schema: schema,
};
editor[id] = new JSONEditor(element, options);
JSONEditor.plugins.sceditor.emoticonsEnabled = element.getAttribute("data-sceditor");
editor[id].on('change', function () {
var errors = editor[id].validate();
if (errors.length) {
console.log(errors);
}
else {
var json = editor[id].getValue();
$('#'+textarea_id)[0].value = JSON.stringify(json);
}
});
if (data != null) {
editor[id].setValue(data);
}

}
}

$(document).ready(function() {
$(document).find("[id$=_editor]").each(function(){
enable_json_editor(this);
});
});

$(document).on('formset:added', function(event, $row, formsetName) {
$row.find("[id$=_editor]").each(function(){
enable_json_editor(this);
});

});
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
<div id="{{ name }}_editor"></div>

<script>
var container = document.getElementById("{{ name }}_editor");
var options = {
theme: "bootstrap3",
iconlib: "fontawesome4",
schema: {{ schema|safe }}
};
var {{ name }}_editor = new JSONEditor(container, options);
JSONEditor.plugins.sceditor.emoticonsEnabled = {{ sceditor }};
{{ name }}_editor.on('change', function () {
var errors = {{ name }}_editor.validate();
if (errors.length) {
console.log(errors);
}
else {
var json = {{ name }}_editor.getValue();
document.getElementById("id_{{ name }}").value = JSON.stringify(json);
}
});
{% if data %}
var json = {{ data|safe }};
{{ name }}_editor.setValue(json);
{% endif %}
</script>

<div id="{{ name }}_editor"
data-sceditor='{{ sceditor }}' data-schema='{{ schema|safe }}'
data-data = '{{ data|safe }}'></div>
<textarea cols="40" id="id_{{ name }}" name="{{ name }}" rows="10" required=""
style="display: none">{{ data|safe }}</textarea>
57 changes: 56 additions & 1 deletion example/app/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from django_admin_json_editor import JSONEditorWidget

from .models import JSONModel, ArrayJSONModel, Tag
from .models import JSONModel, ArrayJSONModel, Tag, OtherJSONModel, RelatedJSONModel


DATA_SCHEMA = {
Expand Down Expand Up @@ -31,6 +31,40 @@
'required': ['text']
}

OTHER_DATA_SCHEMA = {
'type': 'object',
'title': 'Data',
'properties': {
'other_text': {
'title': 'Some other text',
'type': 'string',
'format': 'textarea',
},
'status': {
'title': 'Status',
'type': 'boolean',
},
},
'required': ['other_text']
}

RELATED_DATA_SCHEMA = {
'type': 'object',
'title': 'Data',
'properties': {
'related_info': {
'title': 'Some related info',
'type': 'string',
'format': 'textarea',
},
'relevant': {
'title': 'Relevant',
'type': 'boolean',
},
},
'required': ['related_info']
}


def dynamic_schema(widget):
return {
Expand Down Expand Up @@ -84,3 +118,24 @@ def get_form(self, request, obj=None, **kwargs):
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
pass


class RelatedJSONModelStackedInline(admin.StackedInline):
model = RelatedJSONModel
extra = 0
def get_formset(self, request, obj=None, **kwargs):
widgets = {
'related_data': JSONEditorWidget(RELATED_DATA_SCHEMA, False),
}
return super().get_formset(request, obj, widgets=widgets, **kwargs)

@admin.register(OtherJSONModel)
class OtherJSONModelAdmin(admin.ModelAdmin):
inlines = [ RelatedJSONModelStackedInline, ]
def get_form(self, request, obj=None, **kwargs):
widgets = {
'data': JSONEditorWidget(OTHER_DATA_SCHEMA, collapsed=False),
}
return super().get_form(request, obj, widgets=widgets, **kwargs)


31 changes: 31 additions & 0 deletions example/app/migrations/0004_otherjsonmodel_relatedjsonmodel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 2.1.3 on 2018-12-05 08:44

import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('app', '0003_tag'),
]

operations = [
migrations.CreateModel(
name='OtherJSONModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('data', django.contrib.postgres.fields.jsonb.JSONField(default={'other_text': 'some other text', 'status': True})),
],
),
migrations.CreateModel(
name='RelatedJSONModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('related_data', django.contrib.postgres.fields.jsonb.JSONField(default={'related_info': '', 'relevant': False})),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.OtherJSONModel')),
],
),
]
15 changes: 15 additions & 0 deletions example/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@ class ArrayJSONModel(models.Model):

class Tag(models.Model):
name = models.CharField('name', max_length=10)


class OtherJSONModel(models.Model):
name = models.CharField(max_length=50)
data = JSONField(default={
'other_text': 'some other text',
'status': True,
})

class RelatedJSONModel(models.Model):
parent = models.ForeignKey(OtherJSONModel, on_delete=models.CASCADE)
related_data = JSONField(default={
'related_info': '',
'relevant': False,
})