Registry / web-framework / django-ckeditor

django-ckeditor

JSON →
library6.7.3pypypi✓ verified 23d ago

django-ckeditor integrates the CKEditor 4 WYSIWYG rich text editor into Django projects, providing `RichTextField`, `RichTextUploadingField`, `CKEditorWidget`, and `CKEditorUploadingWidget` for seamless content management in both the admin interface and custom forms. The library is currently at version 6.7.3 and follows Django's release cycle for compatibility updates, though it has an important deprecation warning regarding its bundled CKEditor 4 version.

pip install django-ckeditor
INSTALL
IMPORT
SIG · DJANGO-CKEDITOR
D
django-ckeditor
web-frameworkpythonv6.7.3
Install
3.8s avg
Import
662ms
Disk
76MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v6.7.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.700s · 76.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.8s · import 0.624s · 77MB
76MB installed
● package 76MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

RichTextField
from ckeditor.fields import RichTextField
RichTextUploadingField
from ckeditor_uploader.fields import RichTextUploadingField
Use this field if you need image/file upload capabilities.
CKEditorWidget
from ckeditor.widgets import CKEditorWidget
from django_ckeditors.widgets import CKEditorsWidget
The `django_ckeditors` import path is incorrect/outdated for the main `django-ckeditor` library. Always use `ckeditor.widgets` or `ckeditor_uploader.widgets`.
CKEditorUploadingWidget
from ckeditor_uploader.widgets import CKEditorUploadingWidget
from django_ckeditors.widgets import CKEditorsWidget
The `django_ckeditors` import path is incorrect/outdated for the main `django-ckeditor` library. Always use `ckeditor.widgets` or `ckeditor_uploader.widgets`.

This quickstart demonstrates how to integrate `RichTextUploadingField` into a Django model and use the corresponding form and template. It includes the necessary `settings.py` and `urls.py` configurations, emphasizing the crucial `{{ form.media }}` in the template for CKEditor to render correctly. This example assumes a basic Django project structure with a `base.html` template. Remember to run `python manage.py makemigrations` and `python manage.py migrate` after defining the model, and `python manage.py collectstatic` to gather CKEditor's static files. For file uploads, ensure your `MEDIA_ROOT` and `MEDIA_URL` settings are correctly configured.

import os from django.db import models from django.forms import ModelForm from django.shortcuts import render, redirect from django.urls import path, include from django.conf import settings from django.conf.urls.static import static # --- settings.py additions --- # INSTALLED_APPS = [ # # ... other apps # 'ckeditor', # 'ckeditor_uploader', # ] # # MEDIA_URL = '/media/' # MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # Ensure BASE_DIR is defined # CKEDITOR_UPLOAD_PATH = 'uploads/' # CKEDITOR_CONFIGS = { # 'default': { # 'toolbar': 'full', # 'height': 300, # 'width': '100%', # 'extraPlugins': 'codesnippet', # }, # } # # # --- urls.py additions (project level) --- # # from django.urls import include, path # # from django.conf import settings # # from django.conf.urls.static import static # # # # urlpatterns = [ # # # ... other urls # # path('ckeditor/', include('ckeditor_uploader.urls')), # # ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # --- app/models.py --- from ckeditor_uploader.fields import RichTextUploadingField class Article(models.Model): title = models.CharField(max_length=200) content = RichTextUploadingField(blank=True, null=True) def __str__(self): return self.title # --- app/forms.py --- class ArticleForm(ModelForm): class Meta: model = Article fields = ['title', 'content'] # --- app/views.py --- def create_article(request): if request.method == 'POST': form = ArticleForm(request.POST) if form.is_valid(): form.save() return redirect('article_list') else: form = ArticleForm() articles = Article.objects.all() return render(request, 'app/article_form.html', {'form': form, 'articles': articles}) def article_list(request): articles = Article.objects.all() return render(request, 'app/article_list.html', {'articles': articles}) # --- app/urls.py (within your app) --- # urlpatterns = [ # path('create/', create_article, name='create_article'), # path('', article_list, name='article_list'), # ] # --- app/templates/app/article_form.html --- # {% extends 'base.html' %} # {% block content %} # <h2>Create Article</h2> # <form method="post"> # {% csrf_token %} # {{ form.media }} {# IMPORTANT: Renders CSS/JS for CKEditor #} # {{ form.as_p }} # <button type="submit">Save</button> # </form> # <hr/> # <h2>Articles</h2> # <ul> # {% for article in articles %} # <li>{{ article.title }}</li> # {% endfor %} # </ul> # {% endblock %} # --- app/templates/app/article_list.html --- # {% extends 'base.html' %} # {% block content %} # <h2>Articles</h2> # <ul> # {% for article in articles %} # <li><a href="#">{{ article.title }}</a></li> # <div>{{ article.content|safe }}</div> {# Use |safe to render HTML #} # {% empty %} # <li>No articles yet. <a href="{% url 'create_article' %}">Create one</a>.</li> # {% endfor %} # </ul> # {% endblock %}
Debug
Known issues
breakingVersion 6.4.0 dropped support for Python versions older than 3.8 and Django versions older than 3.2. Ensure your project meets these minimum requirements before upgrading.
fix
Upgrade Python to 3.8+ and Django to 3.2+. Review your codebase for deprecated Django features or Python syntax if upgrading from very old versions.
affects: <6.4.0
breakingIn version 6.0.0, the `ugettext_lazy()` function was replaced with `gettext_lazy()`. If you have custom translations or widget templates that directly use `ugettext_lazy()`, they will break.
fix
Replace all instances of `ugettext_lazy` with `gettext_lazy` in your custom code.
affects: <6.0.0
deprecateddjango-ckeditor bundles CKEditor 4.22.1, which is no longer officially supported by CKSource and has known unfixed security issues. Users are strongly advised to consider switching to CKEditor 5 (using `django-ckeditor-5`) or the non-free CKEditor 4 LTS package for security and continued support.
fix
Evaluate migrating to `django-ckeditor-5` (a separate project that integrates CKEditor 5) or acquire a license for CKEditor 4 LTS. If migrating, be aware that `django-ckeditor-5` has different import paths and configurations.
affects: All versions bundling CKEditor 4 (currently 6.7.3)
gotchaWhen using `RichTextUploadingField` or `CKEditorUploadingWidget`, you must include `'ckeditor_uploader'` in `INSTALLED_APPS` and add `path('ckeditor/', include('ckeditor_uploader.urls'))` to your project's `urls.py`. Failing to do so will result in broken image/file upload functionality and a 404 error when accessing upload URLs.
fix
Ensure both `ckeditor_uploader` is in `INSTALLED_APPS` and its URLs are included in your project's `urls.py`.
affects: All versions
gotchaCustomizing the CKEditor widget template (e.g., `ckeditor/widget.html`) might require adjustments with version 6.4.0 and later due to changes in the widget's context, deviating less from standard Django widget contexts.
fix
Review your custom `ckeditor/widget.html` template and adapt it to the updated context variables. The official documentation or changelog should provide details on the context changes.
affects: >=6.4.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'ckeditor' or ModuleNotFoundError: No module named 'ckeditor_uploader'
The 'ckeditor' or 'ckeditor_uploader' application is not properly installed, not added to INSTALLED_APPS, or the Python environment cannot locate the module.
fix
Ensure `django-ckeditor` is installed (`pip install django-ckeditor`) and both `'ckeditor'` and `'ckeditor_uploader'` are included in your `INSTALLED_APPS` list in `settings.py`.
NoReverseMatch at /path/to/admin/ Reverse for 'ckeditor_uploader:upload' not found or NoReverseMatch 'ckeditor_uploader:upload' is not a registered namespace
The URL patterns for the `ckeditor_uploader` app, which handles file uploads, are not correctly included in your project's main `urls.py` file.
fix
Add `path('ckeditor/', include('ckeditor_uploader.urls'))` to your project's root `urls.py`.
AttributeError: module 'django.db.models' has no attribute 'RichTextUploadingField' or Import 'ckeditor.fields' could not be resolved
The `RichTextUploadingField` (or `RichTextField`) is being imported from the incorrect module; these fields are not directly part of `django.db.models`.
fix
Import `RichTextUploadingField` from `ckeditor_uploader.fields` (`from ckeditor_uploader.fields import RichTextUploadingField`). For `RichTextField`, import from `ckeditor.fields` (`from ckeditor.fields import RichTextField`).
CKEditor not showing in admin (plain textarea instead of rich text editor) or CKEditor widget not loading
This typically occurs due to static files not being collected or served correctly, an incorrect `CKEDITOR_BASEPATH` configuration, or missing `{{ form.media }}` in custom templates.
fix
1. Ensure `'ckeditor'` is in `INSTALLED_APPS` and run `python manage.py collectstatic`. 2. Verify `STATIC_URL`, `STATIC_ROOT`, `MEDIA_URL`, and `MEDIA_ROOT` are correctly configured in `settings.py`. 3. If rendering forms outside the Django admin, ensure `{{ form.media }}` is included in your template. 4. Optionally, explicitly set `CKEDITOR_BASEPATH = STATIC_URL + 'ckeditor/ckeditor/'` in `settings.py`.
Uncaught ReferenceError: CKEDITOR is not defined
CKEditor's static JavaScript files are not being served correctly by Django, preventing the editor from loading and initializing.
fix
Ensure 'ckeditor' is in `INSTALLED_APPS`, `STATIC_URL` is configured, and run `python manage.py collectstatic` to gather static files.
Upgrade
Version history
6.7.3latest on PyPI · released Jun 6, 2025
Audit
Dependencies
DjangorequiredCore framework integration.
PillowoptionalRequired for image processing during file uploads. It is now optional as of older changes where image processing was extracted to backends, but practically essential for `RichTextUploadingField` functionality.
django-js-assetrequiredRequired for Django >= 4.1 compatibility, specifically for handling JS assets within widgets.
Agent activity
27 hits · last 30 days
node
24
Resources
django-ckeditor — pip install django-ckeditor · libregistry