
Security News
GitHub Actions Pricing Whiplash: Self-Hosted Actions Billing Change Postponed
GitHub postponed a new billing model for self-hosted Actions after developer pushback, but moved forward with hosted runner price cuts on January 1.
django-editorjs-fields
Advanced tools
Django plugin for using Editor.js
This plugin works fine with JSONField in Django >= 3.1
pip install django-editorjs-fields
Add django_editorjs_fields to INSTALLED_APPS in settings.py for your project:
# settings.py
INSTALLED_APPS = [
...
'django_editorjs_fields',
]
pip install django-editorjs-fields --upgrade
python manage.py collectstatic # upgrade js and css files
Add code in your model
# models.py
from django.db import models
from django_editorjs_fields import EditorJsJSONField # Django >= 3.1
from django_editorjs_fields import EditorJsTextField
class Post(models.Model):
body_default = models.TextField()
body_editorjs = EditorJsJSONField() # Django >= 3.1
body_editorjs_text = EditorJsTextField()
<!-- template.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
{% load editorjs %}
{{ post.body_default }}
{{ post.body_editorjs | editorjs}}
{{ post.body_editorjs_text | editorjs}}
</body>
</html>
You can add custom Editor.js plugins and configs (List plugins)
Example custom field in models.py
# models.py
from django.db import models
from django_editorjs_fields import EditorJsJSONField
class Post(models.Model):
body_editorjs_custom = EditorJsJSONField(
plugins=[
"@editorjs/image",
"@editorjs/header",
"editorjs-github-gist-plugin",
"@editorjs/code@2.6.0", # version allowed :)
"@editorjs/list@latest",
"@editorjs/inline-code",
"@editorjs/table",
],
tools={
"Gist": {
"class": "Gist" # Include the plugin class. See docs Editor.js plugins
},
"Image": {
"config": {
"endpoints": {
"byFile": "/editorjs/image_upload/" # Your custom backend file uploader endpoint
}
}
}
},
i18n={
'messages': {
'blockTunes': {
"delete": {
"Delete": "Удалить"
},
"moveUp": {
"Move up": "Переместить вверх"
},
"moveDown": {
"Move down": "Переместить вниз"
}
}
},
}
null=True,
blank=True
)
django-editorjs-fields support this list of Editor.js plugins by default:
EDITORJS_DEFAULT_PLUGINS = (
'@editorjs/paragraph',
'@editorjs/image',
'@editorjs/header',
'@editorjs/list',
'@editorjs/checklist',
'@editorjs/quote',
'@editorjs/raw',
'@editorjs/code',
'@editorjs/inline-code',
'@editorjs/embed',
'@editorjs/delimiter',
'@editorjs/warning',
'@editorjs/link',
'@editorjs/marker',
'@editorjs/table',
)
EDITORJS_DEFAULT_CONFIG_TOOLS = {
'Image': {
'class': 'ImageTool',
'inlineToolbar': True,
"config": {
"endpoints": {
"byFile": reverse_lazy('editorjs_image_upload'),
"byUrl": reverse_lazy('editorjs_image_by_url')
}
},
},
'Header': {
'class': 'Header',
'inlineToolbar': True,
'config': {
'placeholder': 'Enter a header',
'levels': [2, 3, 4],
'defaultLevel': 2,
}
},
'Checklist': {'class': 'Checklist', 'inlineToolbar': True},
'List': {'class': 'List', 'inlineToolbar': True},
'Quote': {'class': 'Quote', 'inlineToolbar': True},
'Raw': {'class': 'RawTool'},
'Code': {'class': 'CodeTool'},
'InlineCode': {'class': 'InlineCode'},
'Embed': {'class': 'Embed'},
'Delimiter': {'class': 'Delimiter'},
'Warning': {'class': 'Warning', 'inlineToolbar': True},
'LinkTool': {
'class': 'LinkTool',
'config': {
'endpoint': reverse_lazy('editorjs_linktool'),
}
},
'Marker': {'class': 'Marker', 'inlineToolbar': True},
'Table': {'class': 'Table', 'inlineToolbar': True},
}
EditorJsJSONField accepts all the arguments of JSONField class.
EditorJsTextField accepts all the arguments of TextField class.
Additionally, it includes arguments such as:
| Args | Description | Default |
|---|---|---|
plugins | List plugins Editor.js | EDITORJS_DEFAULT_PLUGINS |
tools | Map of Tools to use. Set config tools for Editor.js See docs | EDITORJS_DEFAULT_CONFIG_TOOLS |
use_editor_js | Enables or disables the Editor.js plugin for the field | True |
autofocus | If true, set caret at the first Block after Editor is ready | False |
hideToolbar | If true, toolbar won't be shown | False |
inlineToolbar | Defines default toolbar for all tools. | True |
readOnly | Enable read-only mode | False |
minHeight | Height of Editor's bottom area that allows to set focus on the last Block | 300 |
logLevel | Editors log level (how many logs you want to see) | ERROR |
placeholder | First Block placeholder | Type text... |
defaultBlock | This Tool will be used as default. Name should be equal to one of Tool`s keys of passed tools. If not specified, Paragraph Tool will be used | paragraph |
i18n | Internalization config | {} |
sanitizer | Define default sanitizer configuration | { p: true, b: true, a: true } |
If you want to upload images to the editor then add django_editorjs_fields.urls to urls.py for your project with DEBUG=True:
# urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
...
path('editorjs/', include('django_editorjs_fields.urls')),
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
In production DEBUG=False (use nginx to display images):
# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
...
path('editorjs/', include('django_editorjs_fields.urls')),
...
]
See an example of how you can work with the plugin here
from django import forms
from django_editorjs_fields import EditorJsWidget
class TestForm(forms.ModelForm):
class Meta:
model = Post
exclude = []
widgets = {
'body_editorjs': EditorJsWidget(config={'minHeight': 100}),
'body_editorjs_text': EditorJsWidget(plugins=["@editorjs/image", "@editorjs/header"])
}

plugin use css property prefers-color-scheme to define a dark theme in browser

The application can be configured by editing the project's settings.py
file.
| Key | Description | Default | Type |
|---|---|---|---|
EDITORJS_DEFAULT_PLUGINS | List of plugins names Editor.js from npm | See above | list[str], tuple[str] |
EDITORJS_DEFAULT_CONFIG_TOOLS | Map of Tools to use | See above | dict[str, dict] |
EDITORJS_IMAGE_UPLOAD_PATH | Path uploads images | uploads/images/ | str |
EDITORJS_IMAGE_UPLOAD_PATH_DATE | Subdirectories | %Y/%m/ | str |
EDITORJS_IMAGE_NAME_ORIGINAL | To use the original name of the image file? | False | bool |
EDITORJS_IMAGE_NAME | Image file name. Ignored when EDITORJS_IMAGE_NAME_ORIGINAL is True | token_urlsafe(8) | callable(filename: str, file: InMemoryUploadedFile) (docs) |
EDITORJS_EMBED_HOSTNAME_ALLOWED | List of allowed hostname for embed | ('player.vimeo.com','www.youtube.com','coub.com','vine.co','imgur.com','gfycat.com','player.twitch.tv','player.twitch.tv','music.yandex.ru','codepen.io','www.instagram.com','twitframe.com','assets.pinterest.com','www.facebook.com','www.aparat.com'), | list[str], tuple[str] |
EDITORJS_VERSION | Version Editor.js | 2.25.0 | str |
For EDITORJS_IMAGE_NAME was used from secrets import token_urlsafe
Use github issues https://github.com/2ik/django-editorjs-fields/issues
FAQs
Django plugin for using Editor.js
We found that django-editorjs-fields demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
GitHub postponed a new billing model for self-hosted Actions after developer pushback, but moved forward with hosted runner price cuts on January 1.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.