📝 Django Todo 프로젝트: 이미지 처리 + Summernote + Bootstrap5 통합 실습 정리

2025. 5. 12. 18:15·과제

📝 Django Todo 프로젝트: 이미지 처리 + Summernote + Bootstrap5 통합 실습 정리


✅ 목표 요약

  1. django-summernote를 활용한 rich text 편집 기능 적용
  2. ImageField + Pillow로 이미지 썸네일 자동 생성 로직 구현
  3. django-cleanup으로 이미지 수정/삭제 시 파일 정리 자동화
  4. Bootstrap5 기반 Form UI 개선 및 정리

📦 필요한 라이브러리 설치

poetry add django-summernote pillow django-cleanup

그리고 settings.py에 다음 설정 추가:

INSTALLED_APPS = [
    ...
    'django_summernote',
    'django_cleanup.apps.CleanupConfig',  # ✅ 파일 자동 삭제 처리
]

📌 Summernote 보안 설정 예시:

X_FRAME_OPTIONS = 'SAMEORIGIN'
SUMMERNOTE_CONFIG = {
    'iframe': False,
    'summernote': {
        'disableDragAndDrop': True,
    },
}

🧱 1. Todo 모델 수정하기

from django.db import models
from PIL import Image
from io import BytesIO
from django.core.files.base import ContentFile
from pathlib import Path

class Todo(models.Model):
    ...
    completed_image = models.ImageField(upload_to='todo/images/', null=True, blank=True)
    thumbnail = models.ImageField(upload_to='todo/thumbs/', null=True, blank=True, default='todo/thumbs/default.png')

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        if self.completed_image:
            image = Image.open(self.completed_image)
            image.thumbnail((300, 300))

            image_path = Path(self.completed_image.name)
            filename_stem = image_path.stem
            file_ext = image_path.suffix
            thumb_name = f'{filename_stem}_thumb{file_ext}'

            temp_thumb = BytesIO()
            image.save(temp_thumb, format=image.format)
            temp_thumb.seek(0)

            self.thumbnail.save(thumb_name, ContentFile(temp_thumb.read()), save=False)
            temp_thumb.close()
            super().save(*args, **kwargs)

🧾 2. TodoForm, TodoUpdateForm 구성

from django import forms
from django_summernote.widgets import SummernoteWidget
from .models import Todo

class TodoForm(forms.ModelForm):
    class Meta:
        model = Todo
        fields = '__all__'
        widgets = {
            'description': SummernoteWidget(),
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'end_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
        }

class TodoUpdateForm(forms.ModelForm):
    class Meta:
        model = Todo
        fields = '__all__'
        widgets = {
            'description': SummernoteWidget(),
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'end_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
            'is_completed': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'completed_image': forms.FileInput(attrs={'class': 'form-control'}),
        }

⚙️ 3. cb_views.py 설정

from .forms import TodoForm, TodoUpdateForm

class TodoCreateView(CreateView):
    model = Todo
    form_class = TodoForm

class TodoUpdateView(UpdateView):
    model = Todo
    form_class = TodoUpdateForm

🛠 4. admin.py 설정

from django_summernote.admin import SummernoteModelAdmin

class TodoAdmin(SummernoteModelAdmin):
    summernote_fields = ('description',)
    fieldsets = (
        (None, {'fields': ('title', 'description', 'completed_image', 'thumbnail')}),
    )

🎨 5. 템플릿 수정 (todo_form.html 등)

📄 todo_list.html

{% for todo in todos %}
  <div class="card">
    <img src="{{ todo.thumbnail.url }}" class="card-img-top" alt="썸네일">
    <div class="card-body">
      <h5>{{ todo.title }} {% if todo.is_completed %}<span class="badge bg-success">Completed</span>{% endif %}</h5>
      ...
    </div>
  </div>
{% endfor %}

📄 todo_form.html

<form method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" class="btn btn-primary">저장</button>
</form>

📌 todo_create.html, todo_update.html → {% include 'todo_form.html' %} 방식으로 구성하세요.


✅ 최종 체크리스트

  • django-summernote 적용 및 XSS 방지 설정
  • Pillow로 썸네일 자동 생성 로직 구현
  • django-cleanup으로 이미지 정리 자동화
  • Bootstrap5로 템플릿 UI 개선
  • Form 및 Admin 최적화 구성 완료

필요시 미디어 루트 설정, static 경로, default 이미지 등록 위치까지 추가 안내 가능합니다 ✅

'과제' 카테고리의 다른 글

[To do list] Django Custom User + 이메일 인증 시스템 구현 가이드 1/2  (0) 2025.05.13
📌 Django Todo 프로젝트: 이미지 업로드 + 썸네일 생성 + Summernote 적용 전체 흐름 정리  (0) 2025.05.12
📚 Django 프로젝트 시작하기 - 가상환경 구축부터 서버 실행까지  (0) 2025.04.30
Flask practice blog 구축 인터페이스(UI) posts.html (3/3)  (0) 2025.04.22
Flask practice blog 구축 API 라우트 설정 posts_routes.py (2/3)  (0) 2025.04.22
'과제' 카테고리의 다른 글
  • [To do list] Django Custom User + 이메일 인증 시스템 구현 가이드 1/2
  • 📌 Django Todo 프로젝트: 이미지 업로드 + 썸네일 생성 + Summernote 적용 전체 흐름 정리
  • 📚 Django 프로젝트 시작하기 - 가상환경 구축부터 서버 실행까지
  • Flask practice blog 구축 인터페이스(UI) posts.html (3/3)
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (787)
      • Python (32)
      • 프로젝트 (110)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (41)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (153)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    basalcellcarcinoma
    global politics
    lawsuitculture
    travel ban
    self-growth
    hotcoffeecase
    life reflection
    trumpmuskclash
    americaparty
    smartphonedurability
    뷔
    RM
    newpoliticalparty
    btscomeback
    youngprofessionals
    urbantrends
    gpterror
    college reunions
    homebartrend
    btsjungkook
    classaction
    titaniumcase
    btsreunion
    bts
    americanlaw
    btsdischarge
    livebroadcast
    chatgpterror
    remittance
    chinanightlife
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
📝 Django Todo 프로젝트: 이미지 처리 + Summernote + Bootstrap5 통합 실습 정리
상단으로

티스토리툴바