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

1. Install django-summernote and configure your project

You can find the GitHub repertory of the project here: 

https://github.com/openescuela/opsatipstutos/tree/main/tips5-summernote

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-summernote

$ pip install django-summernote

Add summernote to the installed apps, add static and media roots

mysite/settings.py

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

    'blogs',
    'django_summernote',
]
.
.
.

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

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

Add the URLs of the Blogs, summernote apps 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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("blogs.urls")),
    path('summernote/', include('django_summernote.urls')),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Run migration, then collect static files 

$ python manage.py migrate
$ python manage.py collectstatic

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

blogs/modes.py

from django.db import models

class Project(models.Model):
    name = models.CharField(max_length=50)
    content = models.TextField(default='ici')

    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 django_summernote.admin import SummernoteModelAdmin
from .models import Project

class ProjectAdmin(SummernoteModelAdmin):
    summernote_fields = ('content',)
    # summernote_fields = '__all__' if you want to use all text fields

admin.site.register(Project, ProjectAdmin)

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>

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 makemigrations
python manage.py migrate
python manage.py runserver

3. Add summernote text editor for user interface

blogs/forms.py

from django_summernote.widgets import SummernoteWidget
from django import forms
from .models import Project

# using as Form
class ProjectForm(forms.Form):
    content = forms.CharField(widget=SummernoteWidget())

# Using as ModelForm
class SecondForm(forms.ModelForm):
    content = forms.CharField(widget=SummernoteWidget())
    class Meta :
        model = Project
        fields = ('name', 'content',)

blogs/views.py

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

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

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>
  {{project.content|safe}}
  {% endfor %}

  <h1>First form</h1>
  <form class="" action="index.html" method="post">
      {{firstform.as_p}}
  </form>

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

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

4. Add a personalized configuration

mysite/settings.py

.
.
.
SUMMERNOTE_CONFIG = {
    # Using SummernoteWidget - iframe mode, default
    'iframe': True,

    # Or, you can set it to `False` to use SummernoteInplaceWidget by default - no iframe mode
    # In this case, you have to load Bootstrap/jQuery sources and dependencies manually.
    # Use this when you're already using Bootstrap/jQuery based themes.
    'iframe': False,

    # You can put custom Summernote settings
    'summernote': {
        # As an example, using Summernote Air-mode
        'airMode': False,

        # Change editor size
        'width': '100%',
        'height': '480',

        # Use proper language setting automatically (default)
        'lang': None,

        # Toolbar customization
        # https://summernote.org/deep-dive/#custom-toolbar-popover
        'toolbar': [
            ['style', ['style']],
            ['font', ['bold', 'underline', 'clear']],
            ['fontname', ['fontname']],
            ['color', ['color']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['table', ['table']],
            ['insert', ['link', 'picture', 'video']],
            ['view', ['fullscreen', 'codeview', 'help']],
        ],
}
}

 

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