My Image

Django 포스팅

[Django] TinyMCE 설치하고 이미지 업로드 403에러 해결하기

Doyeon0430 | 2023년 05월 18일

Django 이미지

이번시간에는 Django에 TinyMCE를 설치해 간편한 텍스트 편집기를 만들어보겠습니다.

admin 관리자 페이지에 적용시키고 템플릿에 보여지는 과정을 진행 할 겁니다.

그리고 설치 초기에는 이미지 업로드에 403 에러가 뜨는데 해결 방법도 남겨보겠습니다.

 

  1. Django 텍스트 편집기 - TinyMCE 설치

  2. Django 텍스트 편집기 - TinyMCE 사용 방법

  3. Django 텍스트 편집기 - image upload 403 해결법

 

 

1. Django 텍스트 편집기 - TinyMCE 설치

TinyMCE는 웹 기반에 사용되는 WYSIWYG(What You See Is What You Get) 텍스트 편집기입니다.

편집도구를 조금 더 수월하게 작업하도록 도와주는 역할을 합니다.

 

1. TinyMCE 설치

pip install django-tinymce

 

2. settings.py

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

 

3. settings.py

TINYMCE_DEFAULT_CONFIG = {
    'cleanup_on_startup': True,
    'custom_undo_redo_levels': 20,
    'selector': 'textarea',
    'theme': 'silver',
    'plugins': '''
        advlist autolink lists link image charmap print preview hr anchor
        pagebreak searchreplace wordcount visualblocks visualchars code
        fullscreen insertdatetime media nonbreaking save table contextmenu
        directionality emoticons template paste textcolor colorpicker textpattern codesample
    ''',
    'toolbar1': '''
        fullscreen preview bold italic underline | fontselect,
        fontsizeselect | forecolor backcolor | alignleft alignright |
        aligncenter alignjustify | indent outdent | bullist numlist table |
        | link image media | codesample
    ''',
    'toolbar2': '''
        visualblocks visualchars | charmap emoticons | insertdatetime
        | hr nonbreaking | template | pagebreak restoredraft | code
    ''',
    'fontsize_formats': "8pt 9pt 10pt 11pt 12pt 13pt 14pt 15pt 16pt 17pt 18pt 24pt 36pt",
    'contextmenu': 'formats | link image',
    'menubar': True,
    'statusbar': True,
    'theme_advanced_resizing': True,
    'image_class_list' : [{'title':"Fluid",'value':'img-fluid','style':{} }],
    'image_caption':True,
    'width': '50%',
    'height': 600,
}

TINYMCE_DEFAULT_CONFIG는 메뉴바를 디자인하는 코드입니다.

toolbar1과 toolbar2에 다양한 기능을 넣어봤습니다.

 

4. urls.py

urlpatterns = [
    path('tinymce/', include('tinymce.urls')),
]

이렇게 되면 프로젝트에서 설치가 완료됩니다.

그럼 이제 장고 관리자 페이지에 TinyMCE 적용하는 방법을 알려드리겠습니다. 

 

 

2. Django 텍스트 편집기 - TinyMCE 사용 방법

이제 models.py나 템플릿에서 직접 사용하는 방법을 알려드리겠습니다.

 

1. models.py

from tinymce.models import HTMLField

class Model(models.Model):
    htmlcontent = HTMLField()

HTMLField이라는 새로운 변수를 선언합니다.

 

TinyMCE 이미지 1

위에 사진과 같이 나오면 성공입니다.

 

2. HTML 코드

<div>
    {{django.htmlcontent|safe}}
</div>

models.py를 html 코드로 가져올 때 뒤에다가 safe를 넣어주셔야합니다.

 

 

3. Django 텍스트 편집기 - image upload 403 해결법

로컬 컴퓨터에서 사진을 가져올 때 에러가 생길 수 있습니다.

그 이유는 보안을 걸어놨기 때문이에요.

 

tinyMCE 이미지 2

위와 같은 오류가 뜨면 아래 방법을 따라해보세요.

 

1. settings.py

DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880

TINYMCE_DEFAULT_CONFIG = {
    "images_upload_url": "upload_image",
}

images_upload url를 추가하고 upload_imgae를 만듭니다.

 

2. urls.py

last_django = Django.objects.last()
last_django_id = last_django.id if last_django else 0

upload_image_patterns = [
    path(f'admin/engineer/django/{number}/change/upload_image', views.upload_image, name='upload_image')
    for number in range(1, 1+last_django_id)
]


urlpatterns = [
    #admin 관리자 수정 url
    *upload_image_patterns,

    #admin 관리자 추가 url
    path('admin/engineer/physics/add/upload_image',views.upload_image, name='upload_image'),
    path('admin/engineer/django/add/upload_image',views.upload_image, name='upload_image'),
    path('admin/engineer/network/add/upload_image',views.upload_image, name='upload_image'),
    path('admin/movie/movie/add/upload_image',views.upload_image, name='upload_image'),
    path('admin/mywork/mywork/add/upload_image',views.upload_image, name='upload_image'),

   #admin 관리자 url
    path('admin/', admin.site.urls),

]

admin 페이지에서 업로드 할 url 주소에 맞게 작성합니다.

그리고 name에 upload_image를 넣어주세요.

upload_image는 방금 위에 추가한 코드에서 나온겁니다.

여기서 주의해야할 점은 모든 upload_image가 path('admin/', admin.site.urls) 보다 위에 있어야 됩니다.

그리고 수정할때 id값에 따라 url이 변하도록 for문으로 묶은 후 마지막 id를 가져오세요.

 

3. veiws.py

from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
...


@csrf_exempt
def upload_image(request, series: str=None, article: str=None):
    if request.method != "POST":
        return JsonResponse({'Error Message': "Wrong request"})

    file_obj = request.FILES['file']
    file_name_suffix = file_obj.name.split(".")[-1]
    if file_name_suffix not in ["jpg", "png", "gif", "jpeg", "JPG", "PNG", "GIF", "JPEG", "jfif"]:
        return JsonResponse({"Error Message": f"Wrong file suffix ({file_name_suffix}), supported are .jpg, .png, .gif, .jpeg .jfif .JPG .PNG .GIF .JPEG"})

    file_path = os.path.join(settings.MEDIA_ROOT, 'folder', file_obj.name)

    if os.path.exists(file_path):
        file_obj.name = str(uuid4()) + '.' + file_name_suffix
        file_path = os.path.join(settings.MEDIA_ROOT, 'folder', file_obj.name)

    with open(file_path, 'wb+') as f:
        for chunk in file_obj.chunks():
            f.write(chunk)

        return JsonResponse({
            'message': 'Image uploaded successfully',
            'location': os.path.join(settings.MEDIA_URL, 'folder', matching_article.slug, file_obj.name)

upload_image를 새로 추가해줘야합니다.

csrf_exempt로 보안을 풀어주시고 JsonResponse로 이미지 파일을 허용합니다.

이렇게 모든 설정값은 다 끝났습니다.

 

tinyMCE 이미지

설정값을 적용하시면 이미지가 정상적으로 업로드됩니다.

글을 마치며 TinyMCE 설치하고 오류 해결방법을 해결해봤습니다.

댓글 (3)

    질문자
    안녕하세요. 작성하신 글을 통해 구현 하였습니다. 이미지 등록은 잘되는데 수정이 되지 않네요. 2번 urls.py 작성된 곳 상단에 ----------- last_django = Django.objects.last() last_django_id = last_django.id if last_django else 0 upload_image_patterns = [ path(f'admin/engineer/django/{number}/change/upload_image', views.upload_image, name='upload_image') for number in range(1, 1+last_django_id) ] ------------------- 이부분이 "change" url이 들어가있고, 포맷 스트링으로 {number}를 받아서 수정하는 글의 인덱스를 받아 오는것 같은데... 가장 상단에 last_django = Django.objects.last() last_django_id = last_django.id if last_django else 0 이부분이 이해가 잘 되지 않네요. 사진 수정은 관리자 페이지에서 특정 글을 선택했을 때의 id 값을 받아와야 할것 같은데 혹시 좀 더 풀어서 설명이나 상단에 임포트 하신 라이브러리 항목 같은거를 더 알 수 있을까요?

    23/11/26 21:01 | 삭제

    질문자
    아 다시 질문드리겠습니다. 이미 작성된 글에서 수정을 선택하고, 이미지를 업로드 하려고 하면, 호출하는 주소가 /{table.id}/change/upload_image 이렇게 되네요. 새로 작성하지않고, 이미 작성된 글에서 이미지를 추가 삽입하는 방법은 없을까요

    23/11/26 21:11 | 삭제

    질문자
    아. 알려주신 코드의 Django.objects.last() 에서 objects 앞에 있는게 모델의 클래스 이름인것을 파악하고, 제꺼로 바꿔서 해결했습니다. 코드를 꼼꼼히 보지 않고 적용한 문제였습니다. 포스팅 매우 훌륭합니다. 감사합니다.

    23/11/26 21:37 | 삭제

간편 댓글 작성

My Image My Image My Image My Image