[장고] Summernote 패키지
많은 웹 개발자들이 웹 애플리케이션에서 사용자가 텍스트를 입력하고 편집할 수 있는 편리하고 직관적인 에디터를 찾고 있습니다. 이러한 요구에 부응하기 위해 Django 프로젝트에 Summernote 패키지를 추가하는 방법을 알아보겠습니다. 핵심 서비스에 집중할 수 있다.
Summernote란
Summernote는 사용하기 쉬운 위지위그(WYSIWYG) 에디터로, 텍스트 입력 창을 풍부하게 만들어줍니다. 사용자들은 복잡한 마크업이나 HTML 코드를 알 필요 없이 간단하게 텍스트를 입력하고 서식을 적용할 수 있습니다. Summernote는 심플함을 추구하는 위지위그 에디터다. 다음과 같은 장점들이 있다.
위지위그
위지위그 편집기는 개발자가 인터페이스나 문서를 작성하는 동안 실제 출력물이 어떻게 보일지를 미리 확인할 수 있는 편집 도구입니다. "보이는 대로"를 의미하는 위지위그는 스타일을 적용한 결과를 즉시 확인할 수 있는 텍스트 에디터로서의 장점을 가지고 있다.
사용의 용이성
Summernote는 장고에 연동하기 쉽우면서도 높은 완성도를 자랑합니다. 무료로 제공되지만, 거의 모든 종류의 텍스트를 손쉽게 입력할 수 있다.
무료
CKEditor 등 다양한 위지위그 에디터가 있지만, 상업적 이용을 위해서는 매월 일정 금액을 지불해야 하는 경우도 많습니다. 그러나 Summernote는 MIT 라이센스를 채택하여, 상업적인 목적으로도 무료로 이용할 수 있습니다.
구현하기
이 블로그 포스트에서는 Django 프로젝트에 Summernote를 통합하는 과정을 단계별로 안내할 것입니다. 시작하기 전에 몇 가지 준비물이 필요합니다. 아래에 필요한 사항을 간략히 나열해 보았습니다.
- Django 프로젝트: Summernote를 통합할 Django 프로젝트가 이미 있어야 합니다. 다음 글을 참고한다.
새 장고 summernote 구현하기 - 가상 환경: 프로젝트에 대한 파이썬 가상 환경을 설정하는 것이 좋습니다.
준비가 되었다면, 이제 Summernote를 Django 프로젝트에 추가하는 과정에 대해 알아보겠습니다. 함께 따라와 주세요!
환경 설정
먼저 django-summernote 패키지를 설치합니다. pip를 사용하여 다음 명령어를 실행하세요:
$ pip3 install django-summernote
설치가 완료되면, Django 프로젝트의 settings.py 파일을 열고 INSTALLED_APPS에 django_summernote를 추가합니다.
# settings.py
INSTALLED_APPS = [
# ...생략...,
'django_summernote',
]
URL 설정
urls.py 파일에 django_summernote의 URL 패턴을 추가합니다. 일반적으로 프로젝트의 최상위 urls.py 파일에 추가합니다.
# urls.py
from django.urls import path, include
urlpatterns = [
# 생략
path('summernote/', include('django_summernote.urls')),
]
그리고 settings.py에 미디어 파일이 저장될 경로를 설정한다.
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
모델 설정
글을 관리하는 post 앱을 새로 생성합니다.
$ python3 manage.py startapp posts
그 다음 models.py를 열고 간단한 post 모델을 정의합니다.
# posts/models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def __str__(self):
return f'{self.title}'
어드민 설정
admin.py 파일에서 모델을 어드민 사이트에 등록할 때 SummernoteModelAdmin을 사용합니다.
from django.contrib import admin
from .models import Post
from django_summernote.admin import SummernoteModelAdmin
class PostAdmin(SummernoteModelAdmin):
pass
admin.site.register(Post, PostAdmin)
추가 설정 (선택사항)
추가적으로, settings.py 파일에서 SUMMERNOTE_CONFIG 변수를 사용하여 Summernote의 다양한 설정을 조정할 수 있습니다.
SUMMERNOTE_CONFIG = {
'summernote': {
'width': '100%',
'height': '400px',
},
'toolbar': [
['style', ['style']],
['font', ['bold', 'italic', 'underline', 'clear']],
['fontname', ['fontname']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['height', ['height']],
['table', ['table']],
['insert', ['link', 'picture', 'video']],
['view', ['fullscreen', 'codeview', 'help']],
],
}
이로써 Django 프로젝트에 Summernote를 통합하는 기본적인 설정이 완료되었습니다. 이를 통해 관리자 페이지에서 WYSIWYG 편집기를 사용할 수 있으며, 다양한 콘텐츠를 손쉽게 편집할 수 있습니다.
포스트 에디터 페이지 만들기
이번에는 관리자 페이지가 아닌 에디터 페이지를 직접 만들어보겠습니다.
섬머노트 위젯 폼 생성
posts 앱에 forms.py 파일을 생성하고 Summernote를 이용하여 content 필드를 등록합니다.
# forms.py
from django import forms
from .models import Post
from django_summernote.widgets import SummernoteWidget
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
widgets = {
'content': SummernoteWidget(),
}
View에서 Form을 불러와서 사용합니다.
from .forms import PostForm
from django.views.generic.edit import FormView
class PostFormView(FormView):
template_name = 'post_add.html'
form_class = PostForm
success_url = '/thanks/'
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
return super().form_valid(form)
url과 view를 연결(mapping)한다.
# posts/urls.py
app_name = 'posts' # url 네임 스페이스
urlpatterns = [
path('add/', views.PostFormView.as_view()),
]
에디터 페이지 템플릿 제작
HTML 템플릿에 form 태그를 작성한다.
<form action="" method="POST">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="등록하기">
</form>
테스트 서버를 실행한 후 해당 URL로 이동하면 브라우저에서 텍스트 에디터를 볼 수 있습니다.
기폰 폰트 사이즈 변경하기
에디터의 기본 속성을 변경해보겠습니다.
1. static/css 폴더 안에 새로운 CSS 파일을 생성하고, 다른 스타일 설정과 구분되도록 custom-summernote.css라는 이름으로 저장합니다. 섬머노트 에디터의 스타일은 이 파일에서 변경할 수 있습니다.
섬머노트 에디터의 스타일은 이 파일에서 변경한다.
2. 아래 스타일을 입력합니다.
.note-editable {
font-size: 16px;
}
3. settings.py에서 CSS의 경로를 입력합니다.
# settings.py
SUMMERNOTE_CONFIG = {
'iframe': True,
'summernote': {
# Cange editor size
'width': '100%',
...
# Customize toolbar buttons
'toolbar': [
['undo', ['undo',]],
...
],
},
# 이 부분을 추가한다.
'css': ('/static/css/custom_summernote.css',),
}
기타 옵션으로 폰트 사이즈 변경 및 커스텀이 가능합니다. 자세한 내용은 여기를 참고하세요.
텍스트 도구 맞춤 설정하기
텍스트 에디터에는 폰트 크기 변경, 이미지 삽입 등 다양한 도구들이 포함되어 있습니다. 일부 도구들은 기본적으로 제공되지만, 불필요한 도구들도 포함되어 있을 수 있습니다. Summernote 에디터를 사용하면 도구 상자를 원하는 대로 커스터마이즈할 수 있습니다. 사용하지 않는 도구를 숨기고 편집 환경을 더 깔끔하게 만들어야 할 때도 있습니다. 사용자 경험에 맞춰 도구들을 커스텀해봅시다.
이는 간단합니다. 값을 입력하기만 하면 됩니다.
이를 위해 settings.py 파일에 다음과 같은 코드를 입력합니다.
SUMMERNOTE_CONFIG = {
'iframe': True,
'summernote': {
# Cange editor size
'width': '100%',
'lang': 'ko-KR',
# Customize toolbar buttons
'toolbar': [
['style', ['style']],
['style', ['bold', 'italic', 'underline', 'clear']],
['para', ['ul', 'ol', 'paragraph']],
['insert', ['link', 'picture']],
['table', ['table']],
],
},
}
이 코드를 통해 에디터의 크기를 조절하고 언어를 설정할 수 있습니다. 또한, 사용하지 않는 도구를 숨기거나 새로운 도구를 추가하여 도구 상자를 원하는 대로 조정할 수 있습니다. 원하는 도구 버튼을 선택하여 편집 환경을 최적화하세요.
옵션
- 삽입 도구 (Insert)
- picture: 이미지 대화상자 열기
- link: 링크 대화상자 열기
- video: 비디오 대화상자 열기
- table: 표 삽입
- hr: 수평선 삽입
- 글꼴 스타일 (Font Style)
- fontname: 글꼴 패밀리 설정
- fontsize: 글자 크기 설정
- fontsizeunit: 글자 크기 단위 설정
- color: 전경 및 배경 색상 설정
- forecolor: 전경 색상 설정
- backcolor: 배경 색상 설정
- bold: 글자 굵게 설정
- italic: 기울임 설정
- underline: 밑줄 설정
- strikethrough: 취소선 설정
- superscript: 위 첨자 설정
- subscript: 아래 첨자 설정
- clear: 글자 스타일 지우기
- 단락 스타일 (Paragraph style)
- style: 선택한 블록 서식 지정
- ol: 정렬된 목록 토글
- ul: 정렬되지 않은 목록 토글
- paragraph: 단락 정렬을 위한 드롭다운
- height: 줄 높이 설정
- 기타 (Misc)
- fullscreen: 선택한 블록 서식 지정
- ol: 정렬된 목록 토글
- ul: 정렬되지 않은 목록 토글
- paragraph: 단락 정렬을 위한 드롭다운
- height: 줄 높이 설정
기타 옵션은 깃허브에 등록된 summernote의 readme를 참고바랍니다.
폰트 사이즈 리스트 바꾸기
1. yoursite/settings.py를 열고 SUMMERNOTE_CONFIG에 폰트 리스트를 추가합니다.
# settings.py
SUMMERNOTE_CONFIG = {
...
'summernote': {
....
# Customize toolbar buttons
'toolbar': [
...
['fontsize', ['fontsize']], # Add this line
],
# Add this line too
'fontSizes': ['12', '16', '20', '24', '36', '48', '64', '82',],
},
}
그리고 기본 폰트 사이즈를 설정할 수 있다. 자세한 내용은 여기를 참고합니다.
자동으로 썸네일 저장하기
Summernote 에디터의 내용은 CharField 혹은 TextField에 저장됩니다.
# models.py
content = models.TextField()
# forms.py
widgets = {
'content': SummernoteWidget(),
}
Summernote 에디터는 이미지를 별도로 저장하지 않습니다. 썸네일 표기에 대해 고민하던 중, 구글 Blogger가 첫 번째 이미지를 썸네일로 사용하는 방식을 활용하기로 했습니다.
content 필드에 HTML 코드가 저장되기 때문에, 이를 파싱하여 이미지를 쉽게 가져올 수 있습니다. 먼저, 파싱을 도와주는 라이브러리를 설치합니다:
$ pip install beautifulsoup4
썸네일을 작게 줄여 저장하는 대신, 이번 글에서는 원리만 설명하므로 이미지 주소만 따로 저장합니다.
먼저, 이미지 주소를 저장할 CharField를 모델에 추가합니다:
thumbnaiil_url = models.CharField(max_length=100, null=True)
이미지를 등록하지 않는 글도 있을 수 있으므로 null 값을 허용합니다.
이제 forms.py나 views.py를 열어 form_valid 메서드를 오버라이딩합니다:
def form_valid(self, form):
obj = form.save(commit=False)
content = form.cleaned_data['content']
imgs = BeautifulSoup(content, "html.parser").findAll("img")
if len(imgs) > 0:
obj.thumbnail_url = imgs[0]['src']
obj.save()
return HttpResponseRedirect(reverse("posts:detail", kwargs={"category":obj.category, "slug":obj.slug}))
commit=False
로 설정하여 데이터베이스에 데이터 반영을 보류합니다.- 사용자가 작성한 내용을
form.cleaned_data['content']
로 가져옵니다. - BeautifulSoup를 사용하여 모든
img
태그를imgs
변수에 담습니다. img
태그가 하나라도 있으면, 첫 번째 이미지의 주소를thumbnail_url
에 저장합니다.save
메서드를 호출하여 사용자가 입력한 정보를 데이터베이스에 기록합니다.
이렇게 하면 Summernote 에디터에서 첫 번째 이미지를 썸네일로 자동 저장할 수 있습니다.
결론
이번 가이드에서는 Django 프로젝트에 Summernote 패키지를 통합하고, 이를 활용하여 다양한 기능을 구현하는 방법을 다루었습니다.
Summernote 설치 및 설정:
먼저, pip install django-summernote 명령어로 Summernote 패키지를 설치했습니다. 그런 다음, settings.py 파일에 django_summernote를 추가하고, urls.py 파일에 Summernote URL 패턴을 등록했습니다. 이후, models.py와 admin.py 파일에서 SummernoteTextField와 SummernoteModelAdmin을 사용하여 Summernote 편집기를 설정했습니다.
Custom CSS 설정:
static/css 폴더에 custom-summernote.css 파일을 생성하고, Summernote 에디터의 스타일을 이 파일에서 변경하도록 설정했습니다.
도구 상자 커스터마이징:
Summernote 에디터의 도구 상자를 원하는 대로 커스터마이즈하는 방법을 설명했습니다. 이를 통해 사용하지 않는 도구를 숨기고, 필요한 도구만 표시하여 편집 환경을 최적화할 수 있었습니다.
자동 썸네일 저장 기능 구현:
BeautifulSoup 라이브러리를 사용하여 Summernote 에디터의 내용에서 첫 번째 이미지를 추출하고, 이를 썸네일로 자동 저장하는 방법을 설명했습니다. 구체적으로는 form_valid 메서드를 오버라이딩하여, 사용자가 작성한 글의 첫 번째 이미지를 썸네일로 저장하는 로직을 구현했습니다.
이를 통해 Django 프로젝트에서 Summernote를 효과적으로 사용하고, 사용자 경험을 향상시킬 수 있는 다양한 방법을 배웠습니다. 각 단계별로 설명한 설정과 코드는 실제 프로젝트에 적용하여 커스터마이즈된 편집기와 자동 썸네일 기능을 구현하는 데 유용할 것입니다.