CKEditor django 사용과 까다로웠던 점

2019-04-13

https://github.com/django-ckeditor/django-ckeditor

SummerNote를 사용하려 했는데 Admin에서는 잘 적용이 되는게 정작 Template에서 잘 안되서 포기하고 CKEditor로 바꿔서 도전했다.

  1. pip install django-ckeditor로 Package를 설치한다.
  2. INSTALLED_APPSckeditor를 추가한다.
  3. Powershell에 $ ./manage.py collectstatic 명령어를 실행시켜준다. 계속할거냐고 물으면 YES 3.1. collectstatic 관리를 위한 명령어이다. (자세한건 상단 원본 링크 참조)
  4. defaults로 static/ckeditor/ckeditor/ 이런 디렉토리를 알고 있으나 문제가 있을 수 있기에 settings.py 하단에 CKEDITOR_BASEPATH = "/my_static/ckeditor/ckeditor/"를 넣어줍니다. 4.1. 공식문서에는 override를 위해 admin/change_form.html를 만들어서 하라는게 있는데 일단 저는 안해도 잘 됐습니다.

파일 업로드를 위한 설정

  1. INSTALLED_APPSckeditor_uploader를 추가합니다.
  2. settings.py에 CKEDITOR_UPLOAD_PATH = "uploads/" 업로드 경로 설정(예시)를 해줍니다. 2.1. 기본 파일 시스템 저장을 사용하면 image.jpg가 저장될 때 /media/uploads/image.jpg와 같이 저장 될 것 입니다. 2.2. 파일명이 생성될 때 메서드를 추가해주고 싶다면 아래와 같이
  # utils.py
  
  def get_filename(filename):
    return filename.upper()
    
  # settings.py
  
  CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'
  1. MEDIA_ROOT 와 MEDIA_URL이 제대로 설정되어 있는지 확인
  2. Project의 urls.py에 추가
urlpatterns = [
    ...
    path('ckeditor/', include('ckeditor_uploader.urls')),
]

사용해보기

Field 가장 간편하게 할 수 있는 방법이다. 필자로 이 방법으로 했다.

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

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

content에 원래 지정해놓은 TextField()를 지우고 그냥 RichTextField()를 넣어주면 된다. import도 잊지 않고 시행한다.

만약에 업로드를 사용하고 싶다면 ckeditor_uploader.fields, RichTextUploadingField를 사용한다.

Widget 위젯으로 사용할수도 있다.

# admin.py

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

from .models import Event

class EventAdminForm(forms.ModelForm):
    description = forms.CharField(widget=CKEditorWidget())
    class Meta:
        model = Event

class EventAdmin(admin.ModelAdmin):
    form = EventAdminForm

admin.site.register(Event, EventAdmin)

S3를 사용하려면 아래의 코드를 settings.py에 넣어야한다. AWS_QUERYSTRING_AUTH = False

https://django-storages.readthedocs.org/en/latest/

Template에 출력해보기

에디터를 넣는건 사실 간단한 일이다. 하지만 HTML에 어떻게 출력을 해야하는지에 대한 정보가 별로 없어서 적어둔다. (나를 위해) 아래의 코드는 실제 오늘 적용했던 HTML 코드다.

{% extends "posts/post_base.html" %}
{% load bootstrap4 %}

{% block post_content %}
<h4>새로운 포스트</h4>
{{ form.media }}
<form method="POST" action="{% url 'posts:create' %}" id="postForm">
    {% csrf_token %}
    {{form.as_p|safe}}
    {% buttons %}
        <button type="submit" class="btn btn-primary">포스팅</button>
    {% endbuttons %}
</form>
{% endblock %}

우선 form.media 이게 사용하고자 하는 Template에 포함되어 있어야 한다. 여기서 form은 본인의 instance에 따라 변경이 가능한 값이다. 하지만 정확히 무슨 역할인지는 아직까지는 모르겠다 ㅠㅠ

CKEditor Django 출력시 <p> 태그 없애기

post.text|safe 와 같이 |safe를 사용해주면 바로 해결된다. (양쪽 중괄호로 닫아줘서 사용해야함 위에 코드같이) safe는 Django에서 지원해주는 기능이다. 출력시 HTML을 없애주는 기능인듯 하다. autoescaping이 꺼져있다면 작동하지 않을 수도 있다니 참고

https://docs.djangoproject.com/en/2.2/ref/templates/builtins/