Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
D

django-ckeditor

> 编程语言
Open source

Django admin CKEditor integration.

2.5K stars0 likes1 views
WebsiteGitHub

About

Django admin CKEditor integration.

Deprecation notice

I do not recommend using this package anymore since the open source version of CKEditor 4 has unfixed security issues. More on this in my blog post <https://406.ch/writing/django-ckeditor/>. Alternatives are listed here on Django Packages <https://djangopackages.org/grids/g/wysiwyg/>. I personally am using django-prose-editor <https://406.ch/writing/django-prose-editor-prose-editing-component-for-the-django-admin/>__. Thanks!

Django CKEditor

.. image:: https://img.shields.io/pypi/v/django-ckeditor.svg :target: https://pypi.python.org/pypi/django-ckeditor

.. image:: https://img.shields.io/pypi/pyversions/django-ckeditor.svg :target: https://pypi.org/project/django-ckeditor/

.. image:: https://img.shields.io/pypi/djversions/django-ckeditor.svg :target: https://pypi.org/project/django-ckeditor/

.. image:: https://github.com/django-ckeditor/django-ckeditor/workflows/Tests/badge.svg :target: https://github.com/django-ckeditor/django-ckeditor/actions

.. image:: https://readthedocs.org/projects/django-ckeditor/badge/?version=latest&style=flat :target: https://django-ckeditor.readthedocs.io/en/latest/

Django admin CKEditor integration.

Provides a RichTextField, RichTextUploadingField, CKEditorWidget and CKEditorUploadingWidget utilizing CKEditor with image uploading and browsing support included.

This version also includes:

#. support to django-storages (works with S3) #. updated ckeditor to version 4.18.0 #. included all ckeditor language and plugin files to make everyone happy! ( only the plugins maintained by the ckeditor develops team <https://github.com/ckeditor/ckeditor-dev/tree/4.6.2/plugins>__ )

.. contents:: Contents :depth: 5

Installation

Required

#. Install or add django-ckeditor to your python path.
   ::

        pip install django-ckeditor

#. Add ``ckeditor`` to your ``INSTALLED_APPS`` setting.

#. Run the ``collectstatic`` management command: ``$ ./manage.py collectstatic``. This will copy static CKEditor required media resources into the directory given by the ``STATIC_ROOT`` setting. See `Django's documentation on managing static files <https://docs.djangoproject.com/en/dev/howto/static-files>`__ for more info.

#. CKEditor needs to know where its assets are located because it loads them
   lazily only when needed. The location is determined in the ``ckeditor-init.js``
   script. and defaults to ``static/ckeditor/ckeditor/``. This does not work all
   the time, for example when using ``ManifestStaticFilesStorage``, any asset
   packaging pipeline or whatnot. django-ckeditor is quite good at automatically
   detecting the correct place even then, but sometimes you have to hardcode
   ``CKEDITOR_BASEPATH`` somewhere. This can be hardcoded in settings, i.e.::

        CKEDITOR_BASEPATH = "/my_static/ckeditor/ckeditor/"

   It is possible to override
   the ``admin/change_form.html`` template with your own if you really need to do
   this, i.e.::

        {% extends "admin/change_form.html" %}

        {% block extrahead %}
        <script>window.CKEDITOR_BASEPATH = '/my_static/ckeditor/ckeditor/';</script>
        {{ block.super }}
        {% endblock %}

   Of course, you should adapt this snippet to your needs when using
   CKEditor outside the admin app.

Required for using widget with file upload

#. Add ckeditor_uploader to your INSTALLED_APPS setting.

#. Add a CKEDITOR_UPLOAD_PATH setting to the project's settings.py file. This setting specifies a relative path to your CKEditor media upload directory. CKEditor uses Django's storage API. By default, Django uses the file system storage backend (it will use your MEDIA_ROOT and MEDIA_URL) and if you don't use a different backend you have to have write permissions for the CKEDITOR_UPLOAD_PATH path within MEDIA_ROOT, i.e.::

    CKEDITOR_UPLOAD_PATH = "uploads/"

When using default file system storage, images will be uploaded to "uploads" folder in your MEDIA_ROOT and urls will be created against MEDIA_URL (/media/uploads/image.jpg).

If you want to be able to have control over filename generation, you have to add a custom filename generator to your settings::

    # utils.py

    def get_filename(filename, request):
        return filename.upper()

::

    # settings.py

    CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'

CKEditor has been tested with django FileSystemStorage and S3BotoStorage. There are issues using S3Storage from django-storages.

#. For the default filesystem storage configuration, MEDIA_ROOT and MEDIA_URL must be set correctly for the media files to work (like those uploaded by the ckeditor widget).

#. Add CKEditor URL include to your project's urls.py file::

path('ckeditor/', include('ckeditor_uploader.urls')),

#. Note that by adding those URLs you add views that can upload and browse through uploaded images. Since django-ckeditor 4.4.6, those views are decorated using @staff_member_required. If you want a different permission decorator (login_required, user_passes_test etc.) then add views defined in ckeditor.urls manually to your urls.py.

Optional - customizing CKEditor editor

#. Add a CKEDITOR_CONFIGS setting to the project's settings.py file. This specifies sets of CKEditor settings that are passed to CKEditor (see CKEditor's Setting Configurations <http://docs.ckeditor.com/#!/guide/dev_configuration>__), i.e.::

   CKEDITOR_CONFIGS = {
       'awesome_ckeditor': {
           'toolbar': 'Basic',
       },
   }

The name of the settings can be referenced when instantiating a RichTextField::

   content = RichTextField(config_name='awesome_ckeditor')

The name of the settings can be referenced when instantiating a CKEditorWidget::

   widget = CKEditorWidget(config_name='awesome_ckeditor')

By specifying a set named default you'll be applying its settings to all RichTextField and CKEditorWidget objects for which config_name has not been explicitly defined ::

   CKEDITOR_CONFIGS = {
       'default': {
           'toolbar': 'full',
           'height': 300,
           'width': 300,
       },
   }

It is possible to create a custom toolbar ::

    CKEDITOR_CONFIGS = {
        'default': {
            'toolbar': 'Custom',
            'toolbar_Custom': [
                ['Bold', 'Italic', 'Underline'],
                ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
                ['Link', 'Unlink'],
                ['RemoveFormat', 'Source']
            ]
        }
    }

If you want or need plugins which are not part of django-ckeditor's plugin set you may specify assets and plugins as follows::

    text = RichTextField(
        config_name='forum-post',

        # CKEDITOR.config.extraPlugins:
        extra_plugins=['someplugin'],

        # CKEDITOR.plugins.addExternal(...)
        external_plugin_resources=[(
            'someplugin',
            '/static/.../path-to-someplugin/',
            'plugin.js',
        )],
    )

Alternatively, those settings can also be provided through
``CKEDITOR_CONFIGS``.

Optional for file upload

#. All uploaded files are slugified by default. To disable this feature, set ``CKEDITOR_UPLOAD_SLUGIFY_FILENAME`` to ``False``.

#. Set the ``CKEDITOR_RESTRICT_BY_USER`` setting to ``True`` in the project's ``settings.py`` file (default ``False``). This restricts access to uploaded images to the uploading user (e.g. each user only sees and uploads their own images).  Upload paths are prefixed by the string returned by ``get_username``.  If ``CKEDITOR_RESTRICT_BY_USER`` is set to a string, the named property is used instead.  Superusers can still see all images. **NOTE**: This restriction is only enforced within the CKEditor media browser.

#. Set the ``CKEDITOR_BROWSE_SHOW_DIRS`` setting to ``True`` to show directories on the "Browse Server" page. This enables image grouping by directory they are stored in, sorted by date.

#. Set the ``CKEDITOR_RESTRICT_BY_DATE`` setting to ``True`` to bucked uploaded files by year/month/day.

#. You can set a custom file storage for CKEditor uploader by defining it under ``CKEDITOR_STORAGE_BACKEND`` variable in settings.

#. You can set ``CKEDITOR_IMAGE_BACKEND`` to one of the supported backends to enable thumbnails in ckeditor gallery.
   By default, no thumbnails are created and full-size images are used as preview.
   Supported backends:

   - ``ckeditor_uploader.backends.PillowBackend``: Uses Pillow

#. With the ``PillowBackend`` backend, you can change the thumbnail size with the ``CKEDITOR_THUMBNAIL_SIZE`` setting (formerly ``THUMBNAIL_SIZE``).
   Default value: (75, 75)

#. With the ``PillowBackend`` backend, you can convert and compress the uploaded images to jpeg, to save disk space.
   Set the ``CKEDITOR_FORCE_JPEG_COMPRESSION`` setting to ``True`` (default ``False``)
   You can change the ``CKEDITOR_IMAGE_QUALITY`` setting (formerly ``IMAGE_QUALITY``), which is passed to Pillow:

    The image quality, on a scale from 1 (worst) to 95 (best). The default is 75. Values above 95
    should be avoided; 100 disables portions of the JPEG compression algorithm and results in
    large files with hardly any gain in image quality.

   This feature is disabled for animated images.

Usage
-----

Field
~~~~~
The quickest way to add rich text editing capabilities to your models is to use the included ``RichTextField`` model field type. A CKEditor widget is rendered as the form field but in all other regards the field behaves like the standard Django ``TextField``. For example::

    from django.db import models
    from ckeditor.fields import RichTextField

    class Post(models.Model):
        content = RichTextField()

**For file upload support** use ``RichTextUploadingField`` from ``ckeditor_uploader.fields``.

Widget
~~~~~~
Alternatively, you can use the included ``CKEditorWidget`` as the widget for a formfield. For example::

    from django import forms
    from django.contrib import admin
    from ckeditor.widgets import CKEditorWidget

    from post.models import Post

    class PostAdminForm(forms.ModelForm):
        content = forms.CharField(widget=CKEditorWidget())
        class Meta:
            model = Post
            fields = '__all__'

    class PostAdmin(admin.ModelAdmin):
        form = PostAdminForm

    admin.site.register(Post, PostAdmin)

**For file upload support** use ``CKEditorUploadingWidget`` from ``ckeditor_uploader.widgets``.

**Overriding widget template**

In Django >=1.11 for overriding ``ckeditor/widget.html`` you have three ways:

#. Place ``ckeditor/widget.html`` in  ``BASE_DIR/templates``

   - Change ``FORM_RENDERER`` to ``TemplateSettings``.

   ::

       FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'

   - Include ``templates`` folder in ``DIRS``

   ::

       TEMPLATES = [{
           ...
           'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
           ...
       }]

   - Add ``'django.forms'`` to ``INSTALLED_APPS``.

#. Place ``ckeditor/widget.html`` in ``your_app/templates`` and place ``'your_app'`` **before** ``'ckeditor'`` and ``'ckeditor_uploader'`` in ``INSTALLED_APPS``.

#. Inherit from ``CKEditorWidget`` and override ``template_name`` with a custom template available in TEMPLATES DIRS as defined settings.py.

   ::

      class MyCustomCKEditorWidget(CKEditorWidget):
         template_name = "templates/custom_ckeditor/widget.html"

Outside of django admin
~~~~~~~~~~~~~~~~~~~~~~~

When you are rendering a form outside the admin panel, you

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言