django-tinymce doesn't show up in admin

I can’t get the django-tinymce module gui to show up in the admin of my django project.

Here’s (tinymce settings are at the end):

import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See

# SECURITY WARNING: keep the secret key used in production secret!

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True


# Application definition



ROOT_URLCONF = 'orag.urls'

        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [

WSGI_APPLICATION = 'orag.wsgi.application'

# Database

    'default': {
        'ENGINE': 'xxxxxx',
        'NAME': 'xxxxxx',
        'USER': 'xxxxxx',
        'PASSWORD': 'xxxxxx',
        'HOST': 'localhost'

# Password validation

        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',

        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',

# Internationalization



USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
# EMAIL_FILE_PATH = str(BASE_DIR.joinpath('sent_emails'))

# print(BASE_DIR)

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

#     'DEFAULT_CENTER': (47.019214, 5.855572),
#     'DEFAULT_ZOOM': 5,
#     'MAX_ZOOM': 20,
#     'MIN_ZOOM':3,
#     'SCALE': 'both',
# }

TINYMCE_JS_URL = STATIC_URL + 'tinymce/tinymce.min.js'


    "height": "320px",
    "width": "960px",
    "menubar": "file edit view insert format tools table help",
    "plugins": "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code "
    "fullscreen insertdatetime media table paste code help wordcount spellchecker",
    "toolbar": "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft "
    "aligncenter alignright alignjustify | outdent indent |  numlist bullist checklist | forecolor "
    "backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | "
    "fullscreen  preview save print | insertfile image media pageembed template link anchor codesample | "
    "a11ycheck ltr rtl | showcomments addcomment code",
    "custom_undo_redo_levels": 10,
    "language": "es_ES",  # To force a specific language instead of the Django current language.


from django.contrib.gis import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.utils.html import format_html

urlpatterns = [
    path('accounts/', include('django.contrib.auth.urls')),
    path('notices/', include('notices.urls')),
    path('_nested_admin/', include('nested_admin.urls')),
    path('tinymce/', include('tinymce.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

And an extract of (imports and the only model class that will be updated through the admin. I skipped the whole file with Inlines and so on, let me know if it’s needed):

class ObjetArchiAdmin(GeoModelAdminMixin, nested_admin.NestedModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': TinyMCE()}
    list_display = ('titre', 'users', 'date', 'id')
    fieldsets = (
        ('État-Civil', {
            'fields': (('titre', 'date', 'users'), 'resume')
        ('Provenance et attribution', {
            'fields': ('point', ('prov_pays', 'prov_region'), ('prov_departement', 'prov_ville'), 'lieu_dit',  'attribution')
        ('Conservation', {
            'fields': (('cons_pays', 'cons_region'), ('cons_departement', 'cons_ville'),('cons_depot', 'cons_no_inventaire'), 'cons_localisation')
        ('Description', {
            'fields': ('description', 'contexte', 'observations_comp', ('materiau', 'stuc', 'polychromie'), 'hauteur_debut')
        ('Analyse et Datation', {
            'fields': ('analyse', 'inedit', 'ref_biblio', 'ref_biblio_2', ('date_chrono_debut', 'date_chrono_fin'), ('citeantique', 'provinceantique'))
    list_filter = ('users__nom',)
    search_fields = (
    autocomplete_fields = ('prov_pays', 'prov_region', 'prov_departement','prov_ville', 'cons_pays', 'cons_region', 'cons_departement', 'cons_ville', 'materiau', 'ensemble', 'provinceantique', 'citeantique', 'monument', 'cons_depot')
    inlines = [OrnementInline, MoulureInline, ComposanteInline, IllusInline]
    pnt = Point(5.855572,47.019214, srid=4326)
    default_lon, default_lat = pnt.coords
    extra = 0

Here’s what the admin looks like:

enter image description here

The TinyMCE editor should show up after “Résumé”. The dimensions are actually good, according the settings, but the interface doesn’t show up. I guess it can’t find the static files but can’t figure out what’s wrong with my paths setup.

Thanks for your help!

Let’s start with the basics - is the console showing the request for TinyMCE?
Does the network tab in the browser’s developer tools show the request?
Did you add TinyMCE to your form’s media assets?

Hi Ken,

The request showed up in both the console and the dev tools. There was a 301 error, and two 302 errors, when requesting static/tinymce/themes/silver/themes.js though. Indeed, there was only silver/themes.min.js in there. So I switched to a distant script, tweaked the settings and it appeared that with TINYCE_COMPRESSOR turned to False, the editor GUI finally showed up.

In the meantime I realized that TinyMCE was not exactly what I was looking for, cause it saves all the HTML formatting “as is” in the database. I think a Markdown approach would best suits the needs of the project, so I installed django-markdownx. Works great so far, let’s see on the long term.

Thanks for your input!

Glad to see that you’ve got a working solution.

I will comment that the 301 and 302 messages are not “errors” - they’re redirects. Had you stayed with this configuration, I’d encourage you to look at those two responses more closely - they’re frequently related to some type of configuration issue.

1 Like

I solved it

python collectstatic