본문 바로가기

Web Programming/Django

Django 장고 텍스트에디터 사용하기(CKeditor)

기존의 Textarea가 아닌 TextEditor 를 통해서 글을 보다 편리하게 작성하고 활용할 수 있다


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


준비물 먼저 

1. FORM 태그를 활용한 템플릿 

2. static, media 태그 


먼저 ckeditor 라이브러리를 설치해준다.


1
$ pip install django-ckeditor
cs


그 다음, App을 연결해준다.


1
2
3
4
5
6
# settings.py
INSTALLED_APPS = [
    ...
    'ckeditor',
    'ckeditor_uploader',
]
cs


그리고 ckeditor path를 설정해준다.


1
2
3
# settings.py
CKEDITOR_UPLOAD_PATH = 'uploads/'
CKEDITOR_IMAGE_BACKEND = "pillow" 
cs


그리고 url을 지정해준다.


1
2
3
4
5
6
# project/blogproject/urls.py
...
urlpatterns = [
    ...
    path('ckeditor/', include('ckeditor_uploader.urls')),
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
cs


다음, Model의 field를 변경해준다.


1
2
3
4
5
6
7
8
9
10
# project/blog/models.py
from ckeditor_uploader.fields import RichTextUploadingField
 
# Create your models here.
class Blog(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    description = RichTextUploadingField(blank=True,null=True)
    body = models.TextField()
#    username = models.CharField(max_length=50)
cs


forms.py 변경해주기!!


# project/blog/forms.py

from django import forms
from .models import Blog

# 만약 모델 기반이 아니라면 forms.Form
class BlogPost(forms.ModelForm):
class Meta:
model = Blog
fields = ['title' , 'description']


그리고 migrate를 해준다.


1
2
$ python manage.py makemigrations
$ python manage.py migrate
cs


그리고 template를 변경해준다.


1
2
3
4
5
6
7
8
9
10
# project/blog/templates/new.html
<div class = "container">
    <form method ="POST">
    {% csrf_token %}
    {{form.media}}    
    {{form.as_p}}
    <br>
        <input class="btn btn dark" type="submit" value="제출하기">
    </form>
</div>
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# project/blog/templates/detail.html
{% extends 'base.html' %}
{% block content %}
<div class="conatiner">
    <h1> {{blog.title}} </h1>
    <p> {{blog.pub_date}} </p>
    <p> {{blog.body}} </p>
    <p>{{blog.description|safe}}</p>
    <br><br>
</div>
 
<a href="{%url 'home'%}">HOME</a>
 
{% endblock%}
cs


그렇게 되면 다음과 같이 에디터가 잘 나타난다.




사용 중에 이미지 업로드 시 파일을 선택하고 send it to server를 눌러줘야

이미지 파일이 서버에 올라가고 잘 동작한다!


### 추가적으로 ckeditor에서는 파일 업로드에 대해 기본적으로 admin 계정을 요구하도록 옵션이 설정되어있다.

방법1)

다음과 같이 staff_member_required가 되어있는 옵션을 지워준다.

그렇게 되면 일반 계정에서도 업로드가 잘 이루어진다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# myvenv\Lib\site-packages\ckeditor_uploader\urls.py
...
if django.VERSION >= (18):
    urlpatterns = [
        url(r'^upload/', staff_member_required(views.upload), name='ckeditor_upload'),
        url(r'^browse/', never_cache(staff_member_required(views.browse)), name='ckeditor_browse'),
    ]
else:
    from django.conf.urls import patterns
    urlpatterns = patterns(
        '',
        url(r'^upload/', staff_member_required(views.upload), name='ckeditor_upload'),
        url(r'^browse/', never_cache(staff_member_required(views.browse)), name='ckeditor_browse'),
    )
 
cs


1
2
3
4
5
6
# myvenv\Lib\site-packages\ckeditor_uploader\urls.py
...
    urlpatterns = [
        url(r'^upload/', views.upload, name='ckeditor_upload'),
        url(r'^browse/', never_cache(views.browse), name='ckeditor_browse'),
    ]
cs


방법2) 아니면 url을 include 해주지 않고 직접 url을 작성해주면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
# project/project/urls.py
 
from django.contrib.auth.decorators import login_required
from ckeditor_uploader import views as views_ckeditor
from django.views.decorators.cache import never_cache
 
urlpatterns = [
...
path(r’^upload/’, login_required(views_ckeditor.upload), name=’ckeditor_upload’),
path(r’^browse/’, never_cache(login_required(views_ckeditor.browse)), name=’ckeditor_browse’),
...
]
cs





# 수정하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# project/blog/views.py
...
def blogedit(request, blog_id):
        # 객체 가져오기
        blog = get_object_or_404(Blog, pk=blog_id)
 
        # 유저 다르면 돌려보내기
        # if blog.username != request.user.username:
        #       return redirect('home')
 
        # 입력된 내용 처리 -> POST
        if request.method == 'POST':
                form = BlogPost(request.POST or None, instance=blog)
                if form.is_valid(): # 잘입력된지 체크
                        post = form.save(commit=False)
                        post.save() # 저장하기
                        return redirect('/blog/'+str(blog.id))
 
        # 빈 페이지 띄워주는 기능 -> GET
        else :
                form = BlogPost(instance=blog)
                return render(request, 'edit.html', {'blog':blog,'form':form})
 
cs

1
2
3
# project/blog/views.py
...    
path('blig/editBlog/<int:blog_id>', blog.views.blogedit, name="editblog"),
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# project/blog/templates/eidt.html
...    
{% extends "base.html" %}
{% block content %}
{% load static %}
 
<form action="{% url 'editblog' blog.id%}" method="POST">
    {% csrf_token %}
    {{form.media}}
    {{form.as_p}}

    <br>
        <input class="btn btn dark" type="submit" value="제출하기">
    </form>
</form>
 
{% endblock content %}
cs



# 업로드 시 파일 이름 수정하기


project/utils.py 파일생성

import datetime
import random

def get_filename(filename):
string = "asdf"
for i in range(1,20):
string+=str(random.randrange(0,10))
return filename.upper()+string



settings.py에 다음의 코드 추가

CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'


'Web Programming > Django' 카테고리의 다른 글

네이버 지도 API 활용하기  (0) 2019.02.22
댓글 기능 추가하기(모델 관계)  (0) 2019.02.20
Form 활용하기  (0) 2019.02.16
Blog 프로젝트 정리  (0) 2019.02.12
페이지 나누기(Pagination)  (0) 2019.02.10