Motivation for Using TinyMCE

For this blog, I'm saving my posts as html in a Django models.TextField

from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    tags = models.ManyToManyField('Tag', blank=True)
    is_published = models.BooleanField(default=False)
    slug = models.SlugField(unique=True, max_length=255)

    def __str__(self):
        return str(self.title)

This works nicely, as I have the full expressive power of html. However, the default Django TextField editor leaves a lot to be desired.

There are a lot of options for rich html and rich markdown editors, but after some research, I decided TinyMCE was a good fit. It has an open source core, with extra premium upgrades available. Their Django promotion page illustrates the benefits.

Django-tinymce Set Up

Installation

First we need to install django-tinymce

pip install django-tinymce

and add django-tinymce to Django's installed apps in settings.py

INSTALLED_APPS = (
    # ...
    'tinymce',
    # ...
)

Adding TinyMCE to project

You can set default settings for django-tinymce to your settings.py file. However, django-tinymce already has default settings via the TINYMCE_DEFAULT_CONFIG parameter, so I decided to adjust the settings at the widget level.

class PostAdminForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = '__all__'
        widgets = {
            'content': TinyMCE(attrs={'cols': 80, 'rows': 30,},
                                mce_attrs={
                                    'height': 600,
                                    'width': 800,
                                    'image_advtab': True,
                                    'image_caption': True,
                                    'menubar': 'file edit view insert format tools table help',
                                    'plugins': 'preview importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap quickbars emoticons accordion',
                                    'toolbar': "undo redo | accordion accordionremove | blocks fontfamily fontsize | bold italic underline strikethrough | align numlist bullist | link image | table media | lineheight outdent indent| forecolor backcolor removeformat | charmap emoticons | code fullscreen preview | save print | pagebreak anchor codesample | ltr rtl",
                                    }),
                    }

Configuring mce_attrs

mce_attrs is a dict of values that is pased to the TinyMCE javascript client. The TinyMCE documentation is comprehensive. 

attrs={'cols': 80, 'rows': 30,} sets the size of the textbox before tinymce loads, and is optional.

image_advtab and image_caption add additional options to the image dialog

menubar, plugins, toolbar set the editor preferences.

Result: Django Rich Text Editor

The result is a rich text editor within a Django admin form:

screenshot of a Django admin TextField form, but with a TinyMCE editor instead of the default textbox

Now I'm able to write my posts in a powerful WYSIWYG editor.