티스토리 뷰

Django에서 S3를 사용한 파일 업로드 기능을 구현해 보면서 작성자(본인) 기준이해하기 어려웠던 부분을 정리해보았다.

 

AWS S3는 쉽게 말하면 클라우드 기반의 객체 스토리지 서비스다. 구글 드라이브처럼 파일을 저장하는(?) 서비스라고 보면 될 것 같다. 그리고 버킷객체(파일)들을 저장하고 관리하는 역할을 한다.

(자세한 개념/원리에 대해 알고 싶다면 인파님 블로그 보면 자세하게 설명되어 있어 좋다. 👍)

 

S3 버킷을 만드는 과정은 다른 블로그 글을 참고하여 만들었다. 😊

📌 S3 버킷 만들기  (버킷 정책)

더보기

 AWS에서 S3 클릭

버킷 만들기 클릭

 

버킷 이름 AWS 리전 선택 후 

버킷 액세스 차단 설정을 해제 (default 값은 모두 차단)하고 버킷을 만든다.

 

만든 버킷의 권한을 누르고 하단에 버킷 정책에 아래 JSON 코드를 넣어 저장한다.

(버킷 이름 부분과 그 외 설정은 공식 문서에 나와있는 대로 버킷 정책 예제를 참고면서 수정해도 좋다.)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1507637373230",
            "Effect": "Allow",
            "Principal": {
                "AWS": "{user_arn}"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::{bucket_name}/*"
        },
        {
            "Sid": "Stmt1507637391106",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{bucket_name}/*"
        }
    ]
}

 

📌 AWS IAM 만들기

더보기

AWS IAM 사용자 만들기

 

만든 사용자로 들어가  하단의 [ 보안 자격 증명 ] 누르고 하단에 액세스 키 만들기 선택

 개발 환경에 사용할 것이므로 로컬 코드 선택 후 다음 누르기

(태그 설정은 건너뜀)

발급받은 액세스 키는 재발급이 안되기 때문에 하단에 .csv 파일로 다운로드하여 보관할 것 

여기서 발급한 액세스 키는 프로젝트 settings.py에 사용된다

IAM > 정책에서 S3 검색 후 AmazonS3 FullAccess 클릭 > 권한 추가 한다

 

 

 

1. 모듈 설치 

Django 프로젝트가 설치되어 있는 가상 환경에 boto3django-storages 모듈을 설치한다.

 

boto3 - Amazon의 S3를 사용하기 위한 모듈

django-storages - 다양한 저장소(S3와 같은)를 사용하기 위한 모듈

 

pip install boto3
pip install django-storages

 

2. S3 설정을 위한 변수 작성 ✏️

Django 프로젝트 내 settings.py에 S3 설정을 위한 변수를 설정한다. (변수명은 공식 문서에 나와있는 그대로 사용)

ACCESS_KEY_ID, ACCESS_SECRET_ACCESS_KEY와 같은 외부에 공개되면 안 되는 정보는 github에 올라오지 않도록 .gitignore 설정해야 한다.

 

Django 프로젝트 내 settings.py에 미디어 파일과 정적 파일을 업로드하기 위한 코드도 마찬가지로 공식 문서에 나와있는 대로 설정했다.

※ 유저(사용자)가 업로드하는 파일을 Django에서는 미디어 파일이라고 부른다.

 

 미디어 파일을 S3에 업로드할 시 

# django < 4.2
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# django >= 4.2
STORAGES = {"default": "storages.backends.s3boto3.S3Boto3Storage"}

 정적 파일을 S3에 업로드할 시

# django < 4.2
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

# django >= 4.2
STORAGES = {"staticfiles": "storages.backends.s3boto3.S3StaticStorage"}

 

settings.py

# .csv 파일에 있는 내용을 입력 Access key ID
# 공개되면 안되기 때문에 따로 환경 변수설정 파일에 코드를 넣고 사용해야한다
AWS_ACCESS_KEY_ID = 'Access key ID' 
AWS_ACCESS_KEY_ID = AWS_ACCESS_KEY_ID # 권장 


# .csv 파일에 있는 내용을 입력 Secret access key
AWS_SECRET_ACCESS_KEY = 'Secret access key'
AWS_SECRET_ACCESS_KEY = AWS_SECRET_ACCESS_KEY # 권장 

# AWS REGUON 넣기
AWS_REGION = 'ap-northeast-2'

#S3 Storages

# Amazon Web Services 스토리지 버킷 이름
AWS_STORAGE_BUCKET_NAME = 'magazine-k' 
AWS_STORAGE_BUCKET_NAME = AWS_STORAGE_BUCKET_NAME # 권장 

# 사용자 지정 도메인을 구성할 때 사용할 프로토콜
AWS_S3_CUSTOM_DOMAIN = '%s.s3.%s.amazonaws.com' % (AWS_STORAGE_BUCKET_NAME,AWS_REGION)

# 모든 객체에 대한 매개변수 설정하기위한 변수 (사용하지 않아도 된다)
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

# S3에 미디어파일, 정적 파일 업로드 
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

 

 

3. 앱의 view.py에 코드 작성하기 (※ url 및 app 설정 등 모두 했다는 전제 하에 작성)

view.py에서 파일이 저장될 S3 버킷 클라이언트를 변수로 선언한다.

request.FILES로 사용자가 업로드할 파일을 받아오면, upload_fileobj 메서드를 사용해 버킷에 저장한다.

 

upload_fileobj 메서드를 사용하면 저장된 url을 통해 바로 이미지를 확인할 수 있고,

upload_file 메서드를 사용하면 로컬 디스크에 저장 후 이미지를 확인할 수 있다.

 

app.view.py

import uuid
import json

import boto3

from django.http       import JsonResponse
from django.views      import View
from mysite.settings   import *

class S3ImgUploader(View):
    def post(self, request):
        s3_client = boto3.client(
            's3',
            aws_access_key_id     = AWS_ACCESS_KEY_ID,
            aws_secret_access_key = AWS_SECRET_ACCESS_KEY
        )

        filename = request.FILES['filename']
        url = str(uuid.uuid4())
        
        s3_client.upload_fileobj(
            filename,     # 받아온 파일
            "magazine-k", # S3 버킷 이름
            url	          # 업로드되는 파일(key)의 이름
        )
        
        return JsonResponse({'Message':'Success', 'url':url}, status=200)

 

 

 

4. Postman으로 파일 업로드 요청하기

Django 서버를 구동한 뒤 Postman으로 파일을 보내면 S3 버킷에 유저가 보낸 파일이 업로드되는지 테스트를 한다.

 

POST Method로 Body에 데이터를 담아 서버로 보내기 때문에 Body - form-data를 선택하고 view.py에서 지정한 key값인 filename을 적어주고 Value에 파일을 선택해서 보낸다. ( view 코드에 파일만 가져오기 때문에 다른 값은 넣지 않았다.)

 

데이터를 보내는 것에 성공하면 Postman은 view에서 설정한 JsonResponse값인 success메시지와 url을 받게 된다.

 

 

AWS S3 bucket에서 동일한 url(파일이름)으로 유저가 업로드한 파일이 들어간 것을 확인할 수 있고,

    저장된 객체를 눌러보면 객체 URL로 업로드된 파일을 열어볼 수 있다

'study > Django' 카테고리의 다른 글

Template - 검색 결과 내 페이지네이션  (0) 2023.05.22
Template 기본 구조  (0) 2023.05.11
환경 변수 설정 (django-environ)  (0) 2023.04.13
Unit Test 작성  (0) 2023.03.02
Django - Query string 2  (0) 2022.09.07
댓글