Integrating a modern, elegant text editor into your Django project can significantly enhance the user experience. Among the many options, Quill.js stands out for its simplicity, rich formatting features, and flexibility. In this post, I’ll walk you through how to use Quill.js with the Bubble theme for inline editing of a Post model in Django—without relying on Django-specific Quill modules. Instead, we'll manually integrate Quill.js into our forms and templates for maximum control.
Why Quill.js?
Quill.js is an open-source WYSIWYG (What You See Is What You Get) editor that offers:
- A customizable toolbar.
- Multiple themes, including Snow and Bubble.
- Easy integration with front-end frameworks.
- Clean, lightweight HTML output.
The Bubble theme is ideal for inline editing, displaying a floating toolbar only when the user interacts with the content.
Step 1: Setting Up the Django Post Model
Here’s a simple Post model to work with:
# models.py from django.db import models class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() # This will be edited with Quill.js created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title
Step 2: Adding Quill.js to Your Project
Download the necessary Quill.js files or include them via a CDN in your base HTML template. For this example, we'll use a CDN.
<!-- base.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{% block title %}Quill.js Demo{% endblock %}</title> <!-- Quill.js --> <link href="https://cdn.quilljs.com/1.3.7/quill.bubble.css" rel="stylesheet"> </head> <body> {% block content %}{% endblock %} <!-- Quill.js --> <script src="https://cdn.quilljs.com/1.3.7/quill.min.js"></script> </body> </html>
Step 3: Customizing the Django Form
We'll create a form for the Post model but won't render the content field directly. Instead, we’ll use a <div> as the editor and handle its data manually.
# forms.py from django import forms from .models import Post class PostForm(forms.ModelForm): class Meta: model = Post fields = ['title', 'content'] widgets = { 'title': forms.TextInput(attrs={'class': 'form-control'}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['content'].widget = forms.HiddenInput() # Hide the default textarea
Step 4: Updating the Template for Quill.js
Here’s how to create a form template for editing posts:
<!-- templates/post_edit.html --> {% extends "base.html" %} {% block content %} <h1>Edit Post</h1> <form method="post" action=""> {% csrf_token %} <div class="form-group"> <label for="id_title">Title:</label> {{ form.title }} </div> <div id="quill-editor" style="min-height: 200px;">{{ form.instance.content|safe }}</div> <input type="hidden" name="content" id="content"> <button type="submit" class="btn btn-primary">Save</button> </form> <script> // Initialize Quill editor var quill = new Quill('#quill-editor', { theme: 'bubble' // Use Bubble theme }); // Sync content with hidden input on form submission document.querySelector('form').onsubmit = function () { document.querySelector('#content').value = quill.root.innerHTML; }; </script> {% endblock %}
Step 5: Adding the View
Create a view to handle both the GET and POST requests for editing a post.
# views.py from django.shortcuts import render, get_object_or_404, redirect from .models import Post from .forms import PostForm def edit_post(request, pk): post = get_object_or_404(Post, pk=pk) if request.method == "POST": form = PostForm(request.POST, instance=post) if form.is_valid(): form.save() return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'post_edit.html', {'form': form, 'post': post})
Step 6: Adding a URL Pattern
Update your urls.py to include the edit view.
# urls.py from django.urls import path from .views import edit_post urlpatterns = [ path('post/<int:pk>/edit/', edit_post, name='edit_post'), ]
Step 7: Styling the Editor (Optional)
If needed, you can add some custom CSS for the editor container:
/* static/css/custom.css */ #quill-editor { border: 1px solid #ddd; padding: 10px; border-radius: 4px; }
Testing It Out
Navigate to the edit page of a post (e.g., /post/1/edit/), and you'll see the Quill.js editor in action. The content field will automatically populate with the existing content, and any changes you make will sync back to the server upon form submission.
Final Thoughts
By manually integrating Quill.js, you gain full control over its behavior and appearance, without being tied to a specific Django module. The Bubble theme makes inline editing intuitive and visually appealing, perfect for modern web applications. With just a few lines of JavaScript, you’ve added a polished, interactive editor to your Django project.
Have you used Quill.js in your projects? Let me know in the comments below!