django-storages s3 이미지 업로드 방법

프로필 사진mingke

django-storages-s3-image-upload

목차

django-storages

오름캠프 파이썬 장고 백엔드 과정의 파이널 프로젝트도 어느 덧 막바지에 이르렀습니다. 파이널 프로젝트에서 AWS를 많이 사용하고 있고 S3에 이미지 파일을 업로드 하는 경우가 많았습니다. django에는 django-storages라는 써드파티 라이브러리가 있는데요. 이걸 활용하면 이 작업을 매우 간단하게 할 수 있어서 django-storages를 이용한 이미지 업로드를 이번 포스팅에서 알아보도록 하겠습니다.

Django 4.2 버젼 이후에는 settings.py 를 작성하는 방법이 달라졌습니다. 이번 포스팅에서 사용 되는 django 버젼은 5.1.2 입니다. django-storages 버젼은 1.14.4 입니다.

django, djangorestframework, django-storages, boto3를 설치해야합니다.

pip install django djangorestframework django-storages boto3

settings.py 설정하기

이 작업은 너무너무 간단합니다.

우선 INSTALLED_APPS에 앱을 추가해줍니다.

INSTALLED_APPS = [
    ...
    "storages",
]

그리고 아래 설정만 해주면 끝입니다.

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": {
            "access_key": "AWS_ACCESS_KEY_ID",
            "secret_key": "AWS_SECRET_ACCESS_KEY",
            "bucket_name": "storages-practice",
            "region_name": "ap-northeast-2",
            "default_acl": "public-read",
            "querystring_auth": False,
        },
    },
    "staticfiles": {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": {
            "access_key": "AWS_ACCESS_KEY_ID",
            "secret_key": "AWS_SECRET_ACCESS_KEY",
            "bucket_name": "storages-practice",
        },
    },
}
  • access_key : AWS의 IAM에서 받은 키를 입력해주면 됩니다.
  • secret_key : AWS의 IAM에서 받은 키를 입력해주면 됩니다. 당연히 S3 권한이 포함되어 있어야 합니다.
  • bucket_name : 생성한 S3 버킷 이름 입니다.
  • region_name : 버킷이 생성되어 있는 region이름 입니다.
  • default_acl : acl 권한을 public-read 로 하여 자유롭게 이미지를 가져올 수 있도록 합니다.
  • querystring_auth : querystring 인증을 False로 하여 빼버렸습니다. 그렇지 않으면 데이터베이스에 querystring 인증이 들어가서 아주 긴 URL이 저장됩니다.

staticfiles 키를 넣지 않으면 에러가 발생합니다. staticfiles를 사용하지 않더라도 반드시 넣어주어야 에러가 발생하지 않더라구요.

간단한 설정은 이렇고 추가적인 셋팅은 공식문서를 참고하시면 됩니다.

Loading...

S3 설정

S3 설정도 크게 어려울 게 없습니다.

  • ACL 활성화 됨을 선택합니다.
s3 생성 옵션1
  • 그리고 우선 모든 퍼블릭 엑세스 차단을 해제해 줍니다.
s3 생성 옵션2

이렇게 세팅을 하고 버킷을 만들어주면 됩니다.

일단 기본적으로 이렇게만 셋팅해도 업로드하고 이미지를 읽어오는 것은 가능합니다.

예제 코드

다음은 테스트를 위해서 사용한 예제코드 입니다.

# models.py
 
class Sample(models.Model):
    image = models.ImageField(upload_to="sample/%Y/%m/%d/")
    created_at = models.DateTimeField(auto_now_add=True)
 
# serializers.py
 
class SampleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sample
        fields = "__all__"
 
# views.py
 
class SampleCreateView(CreateAPIView):
    serializer_class = SampleSerializer
    queryset = Sample.objects.all()
 

upload_to="sample/%Y/%m/%d/" 이 코드를 사용하시면 S3에 년/월/일 디렉토리가 생성되고 그 안에 이미지가 저장됩니다. 이렇게하면 업로드된 이미지를 쉽게 구분할 수 있죠.

view에서 이미지를 업로드하면 다음과 같은 결과를 얻을 수 있습니다.

{
    "id": 1,
    "image": "https://storages-practice.s3.amazonaws.com/sample/2024/10/14/SCR-20241014-onen.png",
    "created_at": "2024-10-14T08:13:29.420997Z"
}

예제 코드 링크는 아래에 있습니다.

Loading...

마무리

너무 간단하게 사용할 수 있어서 길게 쓸 수가 없네요. 추가로 python manage.py collectstatic 하면 staticfile 들이 S3에 저장됩니다. django-storages 를 사용하지 않는다면 boto3를 사용해서 직접 다 구현해줘야 하는데 간단하게 라이브러리를 이용할 수 있는 기능이라면 그냥 라이브러리를 사용하는 것이 좋다고 생각합니다.

Loading...