How to add CkEditor in django

Ckeditor, a WYSIWYG rich text editor allows users to write content directly inside web pages or online applications. A Django WYSIWYG editor built upon CKEditor, you can use it as a standalone widget, or use the provided RichTextField or RichTextUploadingField on your models.

In this tutorial we will discuss:

  1. Installation and configuration
  2. django-ckeditor integration with admin
  3. django-ckeditor integration in your forms and views.
  4. Following django-ckeditor functionalities: Image upload, Youtube videos integration, GIFs integration, Code editor

Installation and Configuration.

Install django-ckeditor.

pip install django-ckeditor

Note: In this tutorial, I am using django==3.2.15 and django-ckeditor==6.0.0

Please make sure you use the same versions. I tried using django-ckeditor==6.3.2 but RichTextUploadingField field was not appearing in the admin panel. So please follow the same steps and versions.

Add ckeditor in INSTALLED_APPS in your settings.py

# settings.py

INSTALLED_APPS = [
    ...
    'ckeditor',
]

Then set STATIC_ROOT in your settings.py file.

# settings.py

# if you are using pathlib Path
STATIC_ROOT = BASE_DIR / 'static'

#if you are using os
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Then run python manage.py collectstatic command. This command will copy the django-ckeditor static and media resources into the directory given by the STATIC_ROOT.

After running this command you will get this message in the terminal and also a folder named static/ckeditor

1383 static files copied to 'your path'.

Also, add media file settings in the settings.py file.

# settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

Then set some ckeditor settings in your settings file

# settings.py 

# CKEditor Settings
CKEDITOR_UPLOAD_PATH = 'uploads/'
CKEDITOR_IMAGE_BACKEND = "pillow"
CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' 

CKEDITOR_CONFIGS = {
    'default':
        {
            'toolbar': 'full',
            'width': 'auto',
            'extraPlugins': ','.join([
                'codesnippet',
            ]),
        },
}

You can check more configurations from the documentation.

Main urls.py

Go to main_project/urls.py and add the following URL.

#urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    .....
    path('admin/', admin.site.urls),
    path('ckeditor/', include('ckeditor_uploader.urls')),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if settings.DEBUG:
    urlpatterns+=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Models.py

We are using RichTextUploadingField for file support.

# models.py

from django.db import models
from django.utils.translation import gettext_lazy as _
from ckeditor_uploader.fields import RichTextUploadingField

class BlogPost(models.Model):
    title = models.CharField(
        _("Blog Title"), max_length=250,
        null=False, blank=False
    )
    body = RichTextUploadingField()

    def __str__(self):
        return self.title

Then run migrations.

Register your models in admin.py

# admin.py

from django.contrib import admin
from .models import BlogPost


admin.site.register(BlogPost)

Then open the admin panel. You will see Ckeditor.

django-ckeditor integration in your forms and views.

# forms.py

from django import forms
from ckeditor_uploader.widgets import CKEditorUploadingWidget

from blogs.models import BlogPost

class BlogForm(forms.ModelForm):
    body = forms.CharField(widget=CKEditorUploadingWidget())

    class Meta:
        model = BlogPost
        fields = '__all__'
# views.py

from django.urls import reverse
from django.views.generic.edit import CreateView
from django.contrib.messages.views import SuccessMessageMixin

from .forms import BlogForm
from .models import BlogPost


class AddBlog(SuccessMessageMixin, CreateView):
    form_class = BlogForm
    model = BlogPost
    template_name = "blogs/add_blogs.html"
    success_message = "Added Succesfully"

    def get_success_url(self):
        return reverse('add_blogs')
# app/urls.py

from django.urls import path
from .views import AddBlog


urlpatterns = [
    path('create/', AddBlog.as_view(), name='add_blogs'),
]

Then add template blogs/add_blogs.html

<!-- blogs/add_blogs.html-->

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    <title>CKEditor</title>
  </head>
  <body>
    
    <!-- for messages -->
    <div class="container">
        {% if messages %}
            {% for message in messages %}
                <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
                {{message}}
                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
                </div>
            {% endfor %}
        {% endif %}
    </div>
    
    <!-- form -->
    <div class="container mt-5">
        <form method="post" enctype="multipart/form-data"> 
            {% csrf_token %} 
            {{ form.media}}
            {% for field in form %}
            <div class="form-group">
                <div><label for="{{ field.id_for_label }}" class="text-dark">{{ field.label }}: </label></div>
                {{ field }}
            </div>
            {% endfor %}
            <div class="row justify-content-center">
                <input type="submit" class="btn btn-info btn-lg" value="Create" />
            </div>
        </form>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
  </body>
</html>

Go to http://127.0.0.1:8000/blogs/create/. You will see following page.

django-ckeditor Functionalities.

How to upload an image in django-ckeditor.

If you are using RichTextField field instead of RichTextUploadingField. Then you won't see Upload option in image upload.

How to add Code snippet in django-ckeditor.

You can add code snippets using the option available on the right side of the insert image.

How to add Youtube videos or GIFs in django-ckeditor.

You can also use youtube videos or GIFs in CKEditor using the Iframe option.

There is another option to add iframes (youtube iframes or any). You can add using the Source button which is the first button in the editor toolbar.

How can I view/add the HTML (source code) of this blog post?

Go to the Source button which is the first button in the editor toolbar. You can add and view HTML using the Source button.

USE CASE: For example, you have an HTML of your blog and you want to copy that to your ckeditor. Then you can add that HTML easily by pressing the Source button.

If you are facing any problem related to described feature then please watch this video.

Source code is available here.

If you like this post then show some love by clapping. You can also support us by buying me a coffee. If you want more content then don't forget to subscribe to our new letter.

Related

How to add CKEditor 5 in django.

I would greatly appreciate it if you subscribe to my YouTube channel, Let's Code More

 ⋅  22 comments have been posted.
    April 4, 2024, 10:19 p.m. - Skye  
    Howdy! Do you know if they make any plugins to assist with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good gains. If you know of any please share. Cheers! I saw similar text here: GSA Verified List
    Reply
    April 4, 2024, 6 a.m. - Annette  
    Hey! Do you know if they make any plugins to assist with SEO? I'm trying to get my site to rank for some targeted keywords but I'm not seeing very good success. If you know of any please share. Cheers! I saw similar art here: Hitman.agency
    Reply
    March 29, 2024, 10:27 p.m. - Britney  
    Hello there! Do you know if they make any plugins to help with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good results. If you know of any please share. Thanks! You can read similar text here: Dobry sklep
    Reply
    March 29, 2024, 9:04 a.m. - Grazyna  
    Good day! Do you know if they make any plugins to assist with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good gains. If you know of any please share. Cheers! You can read similar text here: Najlepszy sklep
    Reply
    March 28, 2024, 7:34 a.m. - Alvin  
    Hi! Do you know if they make any plugins to assist with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good results. If you know of any please share. Cheers! You can read similar article here: Sklep internetowy
    Reply
    March 28, 2024, 3:35 a.m. - Makayla  
    Hello there! Do you know if they make any plugins to assist with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good success. If you know of any please share. Many thanks! You can read similar article here: Ecommerce
    Reply
    March 22, 2024, 7:47 a.m. - May  
    Howdy! I know this is kind of off-topic but I needed to ask. Does operating a well-established blog such as yours take a large amount of work? I'm completely new to operating a blog but I do write in my journal every day. I'd like to start a blog so I will be able to share my own experience and thoughts online. Please let me know if you have any kind of suggestions or tips for brand new aspiring bloggers. Appreciate it! I saw similar here: Sklep
    Reply
    March 14, 2024, 2:14 p.m. - Glen  
    I do trust all of the ideas you have introduced in your post. They are very convincing and will certainly work. Nonetheless, the posts are too short for starters. May just you please lengthen them a bit from subsequent time? Thanks for the post. I saw similar here: Najlepszy sklep
    Reply
    March 2, 2024, 5:53 p.m. - Angelika  
    Normally I don't read article on blogs, but I wish to say that this write-up very forced me to try and do it! Your writing style has been surprised me. Thank you, quite nice post. I saw similar here: sklep and also here: sklep internetowy
    Reply
    Feb. 9, 2024, 12:40 a.m. - Vada  
    Wow, amazing blog format! How lengthy have you been blogging for? you made running a blog look easy. The full look of your site is wonderful, let alone the content! You can see similar: https://camilashop.top and here https://camilashop.top
    Reply
    Nov. 10, 2023, 10:45 p.m. - Ian  
    This is Great! Thanks Areeba.
    Reply
    Sept. 13, 2023, 9:14 p.m. - nasir ahamd ahmady  
    awesome keep up
    Reply
    Feb. 22, 2023, 5:48 a.m. - Ali Haider  
    Nice work Areeba keep it up!
    Reply
    Dec. 1, 2022, 10:52 a.m. - Benny  
    Nice Write up, keep up the good work I have shared this post in my social media , I also added your site to the site i have been writing article for .
    Reply
    Dec. 1, 2022, 10:55 a.m. - Areeba Seher  
    Thank you so much Benny for your appreciation and also thanks for sharing :)
    Reply
    Sept. 28, 2022, 8:40 a.m. - James Sunday  
    Pls which comment package/ tool do you use for your blog. That is if built with django
    Reply
    Sept. 28, 2022, 8:46 a.m. - Areeba Seher moderator  
    Yes, this comment system of my website is built with Django. You can check the article here https://www.letscodemore.com/blog/how-to-create-a-comment-section-for-django-blog/
    Reply
    Sept. 28, 2022, 9:58 a.m. - James Sunday  
    Thank you for the prompt response
    Sept. 28, 2022, 8:38 a.m. - James Sunday  
    Very Helpful
    Reply
    Sept. 28, 2022, 8:44 a.m. - Areeba Seher moderator  
    Thank you. If you want to use ckeditor5 then check this https://www.letscodemore.com/blog/how-to-add-ckeditor5-in-django/
    Reply
    Sept. 24, 2022, 7:02 a.m. - Ashikur Rahman  
    thank you for your resource
    Reply
    Sept. 24, 2022, 11:20 a.m. - Areeba Seher moderator  
    You are welcome Ashikur Rahman. Please subscribe to our newsletter for more content.
    Reply

Your comment

Required for comment verification
claps