Django 예제
주의
서버 보안을 위해 파일 업로드 및 문서 임포트 처리를 구현할 때 아래 가이드를 참고합니다.
1. 기본 정보
통합 가이드는 프로젝트가 다음과 같이 구성되어 있다고 가정합니다:
- 프로젝트 이름:
synapeditor_django - 앱 이름:
edit
1.1 앱 등록
# project settings.py
INSTALLED_APPS = [
'edit.apps.EditConfig', # register the app
# ...
]
# project urls.py
urlpatterns = [
path('edit/', include('edit.urls')), # mount the app's URLs
# ...
]
2. 이미지 / Video / 파일 업로드
주의
아래 샘플 코드의 파일 업로드 부분은 의도적으로 최소화되어 있으며, 적절한 보안 처리가 적용되어 있지 않습니다.
파일 업로드는 프로젝트에 이미 구현된 기능을 사용하고, 아래 코드는 에디터 연동 부분만 참고합니다.
이 가이드에서 사용된 업로드 설정은 다음과 같습니다. 필요에 따라 경로와 API 이름을 변경합니다.
- 이미지 업로드 디렉터리:
media - 이미지 업로드 API:
/edit/uploadFile
2.1 에디터 구성
var SynapEditorConfig = {
// ...
'editor.upload.image.param': { 'csrfmiddlewaretoken': '{{ csrf_token }}' },
'editor.upload.image.api': '/edit/uploadFile',
// ...
};
2.2 미디어 경로 설정
# project settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# project urls.py
urlpatterns = [
# ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
2.3 URL → 뷰 연결
# app urls.py
from django.urls import path
from . import views
urlpatterns = [
# ...
path('uploadFile/', views.upload_file, name='upload_file'),
]
2.4 뷰
응답에는 uploadPath가 포함되어야 합니다.
# app views.py
from django.http import JsonResponse
from .forms import UploadFileForm
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
uploaded_file = form.save()
return JsonResponse({'uploadPath': uploaded_file.file.url})
2.5 폼
# app forms.py
from .models import UploadFile
from django import forms
class UploadFileForm(forms.ModelForm):
class Meta:
model = UploadFile
fields = ('file',)
2.6 모델
# app models.py
import uuid
from django.db import models
def get_file_name(instance, filename):
ext = filename.split('.')[-1]
return "%s.%s" % (uuid.uuid4(), ext)
class UploadFile(models.Model):
file = models.FileField(upload_to=get_file_name)
3. HWP / Word / 엑셀 문서 임포트
주의
아래 샘플 코드의 파일 업로드 부분은 의도적으로 최소화되어 있으며, 적절한 보안 처리가 적용되어 있지 않습니다.
파일 업로드는 프로젝트에 이미 구현된 기능을 사용하고, 아래 코드는 에디터 연동 부분만 참고합니다.
문서 임포트는 다음과 같이 구성되어 있습니다. 필요에 따라 경로와 API 이름을 조정합니다.
- 문서는
media디렉터리에 업로드됩니다. - 변환 결과는
media/output에 저장됩니다. - 문서 임포트 API는
/edit/importDoc입니다.
3.1 에디터 구성
var SynapEditorConfig = {
// ...
'editor.import.param': { 'csrfmiddlewaretoken': '{{ csrf_token }}' },
'editor.import.api': '/edit/importDoc/',
// ...
};
3.2 미디어 경로 설정
2.2절과 동일합니다.
3.3 URL → 뷰 연결
# app urls.py
from django.urls import path
from . import views
urlpatterns = [
# ...
path('importDoc/', views.import_doc, name='import_doc'),
]
3.4 뷰
응답에는 serializedData와 importPath가 포함되어야 합니다.
# app views.py
import os
import subprocess
import zipfile
import zlib
from django.conf import settings
from django.http import JsonResponse
from .forms import UploadFileForm
PROJECT_PATH = os.path.abspath(os.path.dirname(__name__))
MEDIA_ROOT = settings.MEDIA_ROOT
def import_doc(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
uploaded_file = form.save()
# 1. Convert document
result = execute_converter(uploaded_file.file)
if result['resultCode'] == 0:
output_path = result['outputPath']
# 2. Unzip conversion output
unzip_path = unzip(output_path)
pb_path = unzip_path + '/document.pb'
# 3. Serialize the .pb data
serialized_data = serialize_pb(pb_path)
common_prefix = os.path.commonprefix([output_path, PROJECT_PATH])
import_path = '/' + os.path.relpath(unzip_path, common_prefix)
return JsonResponse({
'serializedData': serialized_data,
'importPath': import_path,
})
def execute_converter(file):
fname, ext = os.path.splitext(file.name)
module_path = '{0}/sedocConverter/sedocConverter_exe'.format(PROJECT_PATH)
font_path = '{0}/sedocConverter/fonts'.format(PROJECT_PATH)
input_path = file.path
output_path = '{0}/output/{1}.zip'.format(MEDIA_ROOT, os.path.basename(fname))
temp_path = '{0}/temp'.format(PROJECT_PATH)
args = [module_path, '-z', '-f', font_path, input_path, output_path, temp_path]
result_code = None
process = subprocess.Popen(args)
try:
result_code = process.wait(timeout=20)
except subprocess.TimeoutExpired:
process.kill()
return {'resultCode': result_code, 'outputPath': output_path}
def unzip(zipFilePath):
unzip_path, _ext = os.path.splitext(zipFilePath)
zip = zipfile.ZipFile(zipFilePath)
zip.extractall(unzip_path)
return unzip_path
def serialize_pb(pbFilePath):
serialized_data = []
with open(pbFilePath, 'rb') as pb_file:
pb_file.seek(16)
pb_contents = pb_file.read()
decompressed = zlib.decompress(pb_contents)
for byte in decompressed:
serialized_data.append(byte & 0xFF)
return serialized_data
3.5 폼
2.5와 동일합니다.
3.6 모델
2.6과 동일합니다.
관련 정보
- Java Spring Framework 예제
- Java Servlet 예제
- ASP.NET (C#) 예제
- ASP (Classic) 예제
- PHP 예제
- PHP4 예제
- Django 예제
- Ruby on Rails 예제
- WordPress 플러그인 예제