In this tutorial, you will learn how to use CKEditor (a rich text editor) in your Django web application.

1. Install django-ckeditor and configure your project

You can find the GitHub repertory of the project here: https://github.com/openescuela/opsatipstutos/tree/main/tips3-ckeditor

In this example, the project is named mysite and the application is named blogs.

Open your terminal and go to the repertory of your Django project, active the virtual environment, and install django-ckeditor

$ pip install django-ckeditor

Add CKEditor to the installed app, add CKEditor configuration, add static and media root

mysite/settings.py

.
.
.
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'blogs',
    'ckeditor',
]
.
.
.

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

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


CKEDITOR_UPLOAD_PATH = "uploads/"

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

Add the URLs of the CKEditor app to the urlpatterns of the project.

mysite/urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("blogs.urls")),
    url(r'^ckeditor/', include('ckeditor_uploader.urls')),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

2. Add CKEditor text editor for a model on the admin page

blogs/modes.py

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

class Project(models.Model):
    name = models.CharField(max_length=50)
    image = models.ImageField()
    content = RichTextField()

    def __str__(self):
        return self.name

blogs/views.py

from django.shortcuts import render
from .models import Project

def index(request):
    projects = Project.objects.all()
    return render(request, 'blogs/index.html',{'projects':projects})

blogs/urls.py

from . import views
from django.urls import path

app_name = 'blogs'

urlpatterns = [
    path('', views.index, name='index'),
]

blogs/admin.py

from django.contrib import admin
from .models import Project

admin.site.register(Project)

blogs/templates/blogs/index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title></title>
  
</head>
<body>
  <div class="container">
    <h1> This is my blog </h1>
    {% for project in projects %}
    {{project.name}}
    {{project.content|safe}}
    {% endfor %}
  </div>
  
</body>
</html>

Collect static files, run migration, run the server, go to the admin page, add some projects and go to the browser with the localhost to show the results.

python manage.py collectstatic
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Add a personalized configuration of your text editor 

mysite/settings.py

.
.
.
CKEDITOR_CONFIGS = {
    'default': {
        'skin': 'moono',
        # 'skin': 'office2013',
        'toolbar_Basic': [
            ['Source', '-', 'Bold', 'Italic']
        ],
        'toolbar_YourCustomToolbarConfig': [
            {'name': 'document', 'items': ['Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates']},
            {'name': 'clipboard', 'items': ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']},
            {'name': 'editing', 'items': ['Find', 'Replace', '-', 'SelectAll']},
            {'name': 'forms',
             'items': ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton',
                       'HiddenField']},
            '/',
            {'name': 'basicstyles',
             'items': ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']},
            {'name': 'paragraph',
             'items': ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-',
                       'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl',
                       'Language']},
            {'name': 'links', 'items': ['Link', 'Unlink', 'Anchor']},
            {'name': 'insert',
             'items': ['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe']},
            '/',
            {'name': 'styles', 'items': ['Styles', 'Format', 'Font', 'FontSize']},
            {'name': 'colors', 'items': ['TextColor', 'BGColor']},
            {'name': 'tools', 'items': ['Maximize', 'ShowBlocks']},
            {'name': 'about', 'items': ['About']},
            '/',  # put this to force next toolbar on new line
            {'name': 'yourcustomtools', 'items': [
                # put the name of your editor.ui.addButton here
                'Preview',
                'Maximize',

            ]},
        ],
        'toolbar': 'YourCustomToolbarConfig',  # put selected toolbar config here
        # 'toolbarGroups': [{ 'name': 'document', 'groups': [ 'mode', 'document', 'doctools' ] }],
        # 'height': 291,
        # 'width': '100%',
        # 'filebrowserWindowHeight': 725,
        # 'filebrowserWindowWidth': 940,
        # 'toolbarCanCollapse': True,
        # 'mathJaxLib': '//cdn.mathjax.org/mathjax/2.2-latest/MathJax.js?config=TeX-AMS_HTML',
        'tabSpaces': 4,
        'extraPlugins': ','.join([
            'uploadimage', # the upload image feature
            # your extra plugins here
            'div',
            'autolink',
            'autoembed',
            'embedsemantic',
            'autogrow',
            # 'devtools',
            'widget',
            'lineutils',
            'clipboard',
            'dialog',
            'dialogui',
            'elementspath'
        ]),
    }
}

3. Add CKEditor text editor for user interface

blogs/forms.py

from ckeditor.widgets import CKEditorWidget
from .models import Project
from django import forms

class ProjectForm(forms.ModelForm):
    content = forms.CharField(widget=CKEditorWidget())
    class Meta:
        model = Project
        fields = ('name',)

blogs/views.py

from django.shortcuts import render
from .models import Project
from .forms import ProjectForm

def index(request):
    projects = Project.objects.all()
    form = ProjectForm()
    return render(request, 'blogs/index.html',{'projects':projects, 'form':form})

blogs/templates/blogs/index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <h1> This is my blog </h1>
  {% for project in projects %}
    <h2>{{project.name}}</h2>
    <a href="{{project.image.url}}" download> {{project.name}}</a>
    {{project.content|safe}}
  {% endfor %}

  <form class="" action="index.html" method="post">
    {{form.media}}
    {{form.as_p}}
  </form>
  </body>
</html>

Run your server and go to your browser with the localhost.

0 comment

There are no comments yet.

Log in to leave a reply

Related posts

Developing a Web Application with Django Part 1: Getting Started

1/12/2021

Developing a Web Application with Django Part 2: Templates

15/12/2021

Developing a Web Application with Django Part 3 : Models

7/1/2022