Django Visual Editor: Modern Block‑Based Editing for Django
6 декабря 2025 г.The Django Visual Editor is a powerful, block‑based visual editor designed specifically for Django projects. It brings a rich, WYSIWYG‑style editing experience to the Django admin and any custom forms, while keeping the output clean and CSS‑free thanks to inline styles. The package is available on PyPI, making installation and updates straightforward.
Why Use Django Visual Editor?
- Block‑Based Architecture: Six built‑in block types (paragraph, heading H1‑H6, ordered/unordered list, code, quote, image) let authors structure content intuitively.
- Contextual Toolbar: When a block is selected, a floating toolbar shows only the relevant formatting options.
- Inline Styles: Text alignment, size, color, bold/italic/underline, and image dimensions are stored directly in the HTML as inline styles—no external CSS required.
- Image Management: Drag‑and‑drop upload, on‑the‑fly resizing, double‑click replacement, and alignment controls.
- AI Assistant (optional): Integrated content generation and editing powered by OpenAI, Yandex GPT, or any compatible API.
- Developer‑Friendly: Full TypeScript source, easy block‑API extension, HTML import/export, and a management command for cleaning unused images.
Installation
Quick start via PyPI
pip install django-visual-editor
# or, with AI support
pip install django-visual-editor[ai]
From source (development)
git clone https://github.com/hvlads/django-visual-editor.git
cd django-visual-editor
pip install -e ".[ai]" # install Python deps (including AI extras)
cd frontend
npm install
npm run build # or npm run dev for hot‑reloading
Configuration in Django
Add the app to INSTALLED_APPS and configure media handling:
# settings.py
INSTALLED_APPS = [
# …
'django_visual_editor',
# …
]
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
Include the editor’s URLs (required for image upload and AI endpoints):
# urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.urls import include, path
urlpatterns = [
# …
path('editor/', include('django_visual_editor.urls')),
# …
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Run migrations to create the image model:
python manage.py migrate
Enabling the AI Assistant (optional)
If you installed the [ai] extra, configure the AI back‑ends in settings.py:
import os
VISUAL_EDITOR_AI_CONFIG = {
'enabled': True,
'default_model': 'yandex-gpt',
'temperature': 0.7,
'max_tokens': 2000,
'models': [
{
'id': 'yandex-gpt',
'name': 'YandexGPT',
'provider': 'Yandex',
'model': f"gpt://{os.getenv('YANDEX_FOLDER_ID')}/yandexgpt/latest",
'api_key': os.getenv('YANDEX_API_KEY'),
'base_url': 'https://llm.api.cloud.yandex.net/v1',
'project': os.getenv('YANDEX_FOLDER_ID'),
},
{
'id': 'gpt-4o',
'name': 'GPT‑4o',
'provider': 'OpenAI',
'model': 'gpt-4o',
'api_key': os.getenv('OPENAI_API_KEY'),
'base_url': None,
'project': None,
},
],
}
Remember to set the environment variables (e.g., in a .env file):
YANDEX_API_KEY=your‑yandex‑key
YANDEX_FOLDER_ID=your‑folder‑id
OPENAI_API_KEY=sk‑your‑openai‑key
Using the Editor in Your Models
Option 1 – VisualEditorField (recommended)
# models.py
from django.db import models
from django_visual_editor import VisualEditorField
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = VisualEditorField(
config={
'min_height': 400,
'max_height': 800,
'placeholder': 'Start typing your article…',
}
)
The field automatically wires the widget into Django admin, ModelForms, and the Django REST Framework (if you expose the field).
Option 2 – Manual widget on a regular TextField
# models.py
from django.db import models
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = models.TextField() # plain TextField
# forms.py
from django import forms
from django_visual_editor import VisualEditorWidget
from .models import BlogPost
class BlogPostForm(forms.ModelForm):
class Meta:
model = BlogPost
fields = ['title', 'content']
widgets = {
'content': VisualEditorWidget(
config={
'min_height': 400,
'max_height': 800,
'placeholder': 'Start typing your article…',
}
),
}
# admin.py
from django.contrib import admin
from .models import BlogPost
from django import forms
from django_visual_editor import VisualEditorWidget
class BlogPostAdminForm(forms.ModelForm):
class Meta:
model = BlogPost
fields = '__all__'
widgets = {
'content': VisualEditorWidget(),
}
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
form = BlogPostAdminForm
Rendering the Content
The editor stores clean HTML with inline styles, so you can safely render it using the safe filter:
{{ post.title }}
{{ post.content|safe }}
Full Form Example (including media assets)
{% csrf_token %}
{{ form.as_p }}
{{ form.media }}
Save
Cleaning Up Unused Images
The package provides a management command that scans the media folder and removes images that are no longer referenced in any editor content.
# Dry‑run (shows what would be deleted)
python manage.py cleanup_editor_images --dry-run
# Actual deletion
python manage.py cleanup_editor_images
Schedule this command with cron or a task scheduler to keep your media directory tidy.
Example Project
An example_project is shipped with the repository. To try it locally:
cd example_project
python manage.py migrate
python manage.py createsuperuser # follow prompts
python manage.py runserver
Then open:
Project Structure Overview
django-visual-editor/
├── django_visual_editor/ # Django app (models, widgets, views, URLs)
│ ├── fields.py
│ ├── widgets.py
│ ├── ai_service.py
│ ├── management/
│ └── static/ & templates/
├── frontend/ # TypeScript source of the editor
│ ├── src/
│ │ ├── blocks/ # Paragraph, heading, list, etc.
│ │ ├── editor/ # Toolbar, block menu, AI panel
│ │ └── utils/
│ └── webpack.config.js
└── example_project/ # Ready‑to‑run demo
Conclusion
Django Visual Editor fills a niche for developers who need a rich, block‑based editing experience without the overhead of external CSS frameworks. Its inline‑style approach guarantees that the generated HTML looks the same everywhere, and the optional AI assistant can accelerate content creation. Installation is as simple as a pip command, and the API is designed to work out‑of‑the‑box with Django models, forms, and the admin interface.
For the latest updates, detailed documentation, and contribution guidelines, visit the official repository on GitHub and the package page on PyPI.