Por qué GrapesJS encaja con Django
GrapesJS es un editor exclusivo para navegador y licenciado por MIT, por lo que el papel de Django es simplemente Sirve la plantilla del editor y expone dos puntos finales — uno para cargar la partida guardada y uno para almacenarlo. Esta guía construye una configuración funcional: una plantilla que aloja el editor, una vista que persiste contenido con protección CSRF, y Exportación HTML/CSS.
1. Renderizar el editor en una plantilla
Crear templates/editor.html. Django establece un csrftoken
automáticamente las cookies; lo leemos en JavaScript para la solicitud de guardado.
{% load static %}
<!doctype html>
<html>
<head>
<link href="https://unpkg.com/grapesjs/dist/css/grapes.min.css" rel="stylesheet">
</head>
<body>
<div id="gjs"><h1>Edit me in GrapesJS</h1></div>
<script src="https://unpkg.com/grapesjs"></script>
<script src="{% static 'js/editor.js' %}"></script>
</body>
</html>
2. Inicializar GrapesJS con almacenamiento remoto
En static/js/editor.js, lee la cookie CSRF y configura el
Gestor de almacenamiento a POST a Django.
function getCookie(name) {
const match = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
return match ? match.pop() : '';
}
const editor = grapesjs.init({
container: '#gjs',
height: '100vh',
fromElement: true,
storageManager: {
type: 'remote',
stepsBeforeSave: 3,
options: {
remote: {
urlStore: '/editor/save/',
urlLoad: '/editor/load/',
headers: { 'X-CSRFToken': getCookie('csrftoken') },
},
},
},
});
3. Añadir el modelo, las vistas y las URLs
Guarda el proyecto como JSON en un modelo:
# models.py
from django.db import models
class Page(models.Model):
key = models.SlugField(unique=True, default="home")
project = models.JSONField(default=dict) # full editable project
html = models.TextField(blank=True)
css = models.TextField(blank=True)
# views.py
import json
from django.http import JsonResponse
from django.shortcuts import render
from .models import Page
def editor(request):
return render(request, "editor.html")
def load(request):
page, _ = Page.objects.get_or_create(key="home")
return JsonResponse(page.project, safe=False)
def save(request):
data = json.loads(request.body or "{}")
Page.objects.update_or_create(
key="home",
defaults={
"project": data,
"html": data.get("gjs-html", ""),
"css": data.get("gjs-css", ""),
},
)
return JsonResponse({"status": "ok"})
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path("editor/", views.editor),
path("editor/load/", views.load),
path("editor/save/", views.save),
]
Como la petición lleva el X-CSRFToken encabezado,
CsrfViewMiddleware acepta el POST sin que desactives el CSRF.
4. Renderizar la página exportada
<style>{{ page.css|safe }}</style>
{{ page.html|safe }}
Solo marca el marcado |safe almacenado cuando tus editores sean de confianza;
Limpia la salida si no.
Trampas comunes en Django
Dos problemas complican la mayoría de las integraciones de Django. La primera es CSRF: si configuras CSRF_COOKIE_HTTPONLY = True, JavaScript no puede leer la csrftoken cookie, así que el X-CSRFToken encabezado queda vacío y el POST es rechazado — mantenlo legible o renderiza el token en la plantilla. La segunda es el tipo de almacenamiento: usa a JSONField para el proyecto completo, no un TextField análisis manual, para que los datos se recarguen exactamente en el editor. En producción, la estática editor.js del editor también debe ser recogida y collectstatic servida (WhiteNoise o una CDN), o la página carga GrapesJS pero nunca lo inicializa.
Requisitos previos
Necesitarás Python 3.10+ y un proyecto de Django 4 o 5. Node.js es opcional — carga GrapesJS desde una CDN en una plantilla, o empaquetalo con tu cadena de herramientas de assets. Ahí no es un paquete GrapesJS específico para Django; El editor se ejecuta en el navegador y habla a tus vistas sobre HTTP, por lo que familiaridad con plantillas, vistas, URLs y Django La cookie CSRF es todo lo que necesitas.
Añadir bloques personalizados al editor
Registrar bloques de construcción arrastrables con el Gestor de bloques después de grapesjs.init:
editor.BlockManager.add('hero', {
label: 'Hero section',
category: 'Sections',
content: '<section class="hero"><h1>Headline</h1><p>Copy</p></section>',
});
Busca librerías de bloques y presets listos de GJS. Haz marketing para un set inicial más rico.
Análisis profundo del almacenamiento: un adaptador personalizado
El preset remoto es el camino más rápido, pero un adaptador de almacenamiento personalizado te da control total sobre cómo se carga y guarda el proyecto — útil para una interfaz optimista o almacenes no estándar:
function getCookie(name) {
const m = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
return m ? m.pop() : '';
}
editor.Storage.add('django-store', {
async load() {
const res = await fetch('/editor/load/');
return res.ok ? res.json() : {};
},
async store(data) {
await fetch('/editor/save/', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') },
body: JSON.stringify(data),
});
},
});
// then: storageManager: { type: 'django-store' }
Guarda el proyecto en un JSONField sitio para que se recargue exactamente en el editor.
Consejos de rendimiento
Sirve el JavaScript del editor solo en la página del editor y difértalo para que nunca lo haga
Primero los bloques. Almacenar en caché la página publicada (framework de caché de Django o una CDN)
y invalidar al guardar. En producción, los archivos estáticos del editor deben recopilarse
por collectstatic y servido por WhiteNoise o una CDN, o la página se carga
GrapesJS pero nunca se inicializa.
Consideraciones de seguridad
Mantén activada la protección CSRF y envía el token en la X-CSRFToken cabecera.
Protege la vista de guardado con login_required una comprobación de permisos para que
solo los usuarios autorizados pueden sobrescribir una página. Mark almacenaba el marcado |safe
Solo cuando se confíe en los editores — de lo contrario, sanea en la producción. Limita la petición
tamaño corporal para que un proyecto sobredimensionado no pueda agotar la memoria.
Resolución de errores comunes
403 Prohibido (CSRF) significa que la csrftoken cookie es
ilegible (a menudo CSRF_COOKIE_HTTPONLY = True) o el encabezado es
desaparecido. Un lienzo sin estilo significa que la hoja de estilos de GrapesJS no lo hizo
carga. Un editor en blanco significa que el selector de contenedores no coincide con nada.
413 significa que la carga útil del proyecto supera el límite corporal de tu servidor.
Cuándo usar GrapesJS con Django
GrapesJS encaja cuando tu app de Django necesita una página visual incrustada o un generador de correo electrónico Tus usuarios controlan, respaldados por tus propios modelos y servidos desde tu infraestructura. Para texto enriquecido en línea en un solo campo, un WYSIWYG más ligero es suficiente; para página completa composición con maquetación, estilo y exportación limpia en HTML/CSS, GrapesJS es el una opción más fuerte, con licencia MIT y autoalojada.
Próximos pasos
Extiende el editor con bloques y plugins. Véase el relacionado Guía GrapesJS + React , navega Plugins de adaptadores de almacenamiento y la versión completa Mercado GrapesJS, o empieza desde el GJS. Página principal del mercado.
Preguntas frecuentes
¿Cómo guardo contenido de GrapesJS en un backend de Django?
Configura el Gestor de Almacenamiento con type: 'remote' y apuntar
urlStore/urlLoad en las URLs de Django. Envía el token CSRF en
el X-CSRFToken encabezado, y luego almacenar el JSON del proyecto en un campo modelo.
¿Dónde debería guardar los datos del proyecto?
Usa a JSONField para el proyecto completo para que se recargue en el editor
Exacto, además de campos opcionales de texto html/css para publicar.
¿Cómo envío el token CSRF de GrapesJS a Django?
Lee la csrftoken cookie en JavaScript y pásala como la
X-CSRFToken encabezado en la opción del Administrador headers de Almacenamiento.
