장고에서 media 파일을 다루는 방법

guava·2021년 11월 7일
0

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 강의를 듣고 정리한 글입니다.

settings.py에서 media 관련 설정하기

  • MEDIA_URL: 파일에 대해 어떤 URL을 통해 접근하는지 결정한다.
  • MEDIA_ROOT: 실제 파일을 저장할 ROOT 경로이다. (AWS S3 등으로 설정이 가능)
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media' # 구버전은 os.path.join(BASE_DIR, 'media')

모델 필드 예시

  • photo라는 이름의 ImageField를 정의하였다.
  • ImageField를 사용하려면 pillow 라이브러리를 설치해야 한다. → pip install pillow
  • 장고는 ImageField 또는 FileField에는 파일 경로(문자열)를 저장하고 settings.MEDIA_ROOT 경로에 실제 파일을 저장한다.
  • ImageField, FileField의 upload_to인자 유형
    • 문자열로 지정: 파일을 저장할 중간 디렉토리 경로로서 활용된다.
    • 함수로 지정: 중간 디렉토리 경로 및 파일명까지 결정이 가능하다.
# models.py
from django.db import models


class Post(models.Model):
    message = models.TextField()
    is_publish = models.BooleanField(default=False)
    
    # FileField 또는 ImageField를 사용해서 저장할 수 있다.
    # upload_to에는 문자열 또는 함수의 지정이 가능하다.
    photo = models.ImageField(blank=True, upload_to=uuid_name_upload_to) 
    # uuid_name_upload_to 함수를 지정하였다. 이 함수는 다음 예제에서 정의한다.
    # 또는 'post/%Y/%m/%d'와 같이 문자열 지정이 가능하다.
    
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.message

uuid를 통해 파일명을 정하기

모델의 ImageField 또는 FileField의 upload_to 속성에 지정할 함수

# utils.py
import os
from uuid import uuid4
from django.utils import timezone

def uuid_name_upload_to(instance, filename):
    app_lebel = instance.__class__._meta.app_label  # 앱 이름
    cls_name = instance.__class__.__name__.lower()  # 모델 이름
    ymd_path = timezone.now().strftime('%Y/%m/%d')  # 업로드하는 연/월/일
    uuid_name = uuid4().hex  # 랜덤 문자열
    extension = os.path.splitext(filename)[-1].lower()  # 소문자 형식의 확장자 추출
    return '/'.join([
        app_label,
        cls_name,
        ymd_path,
        uuid_name[:2],
        uuid_name + extension,
    ])

개발환경에서의 media 파일 서빙

# urls.py
from django.conf import settings
from django.conf.urls.static import static

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0개의 댓글