ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Django - S3 - nginx - 이미지업로드, 정적파일
    공부/Django 2023. 3. 7. 23:36

    장고를 사용하면서 해결해야 할 부분 들이 많다.

    이미지를 s3에 저장하는 방법도 그 중 하나다.

     


    S3 만들기

    1. AWS S3 Bucket 생성

    - 우측 버킷 만들기 클릭

     

    - 버킷 이름은 내가 정하면 된다. (ex. turoerial)

    - 객체 소유권은 권장이라고 되어 있지만, 내 프로젝트에서는 ACL 활성화로 하였다.(에러를 겪었기때문에 변경)

    - 액세스 차단 해제( 차단 박스 해제해서 모두 빈박스로)

    - 따로, 큰 설정 할 부분은 없다 ( 참고 영상 ) 해당 영상은 외국 개발자의 영상이지만 쉽게 잘 설명하고 있다.

    - 영상을 보면 aws access id, access key를 쉽게 발급 받을 수 있다. (꼭 영상 참고)

    - 영상에서 버킷 정책까지도 설정 할 수 있게 알려주니 필히 보고 따라해보길

     

     


    Django에 AWS S3 Bucket  연결

    1. boto3, django-storages

    더보기

    pip install boto3

    pip install django-storages

    - 내가 발급 방은 key와 s3의 연결성을 확인 할 수 있는 방법이 있다.

    더보기

    python manage.py shell 을 입력

    >> import boto3

    >> s3r = boto3.resource('s3', aws_access_key_id='발급 받은 키', aws_secret_access_key='발급받은 비밀키')

    >> s3r

    s3.ServiceResource()

    - s3.ServiceResource() 라고 출력이 되면 연결이 잘된것이다.

    2. settings.py  설정

    더보기
    INSTALLED_APPS = [
    ....
    'storages',
    ]

     

    # --- S3 settings ---
    AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') # 발급받은 키 ID
    AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') # 발급받은 키 
    AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') # 내 버킷 name
     
     
    AWS_REGION = 'ap-northeast-2'
    AWS_S3_CUSTOM_DOMAIN = '%s.s3.%s.amazonaws.com' % (AWS_STORAGE_BUCKET_NAME, AWS_REGION
    AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
    }

    AWS_DEFAULT_ACL='public-read'

    AWS_S3_HOST = 's3.ap-northeast-2.amazonaws.com'

    AWS_QUERYSTRING_AUTH = False

     

    # Static Setting
    STATIC_URL = 'https://%s/static/'%(AWS_S3_CUSTOM_DOMAIN)
    STATICFILES_STORAGE = '내프로젝트명.asset_storanges.StaticStorage' # 프로젝트명은 wsgi,url등이 있는 위치와 동일하게
     
    # Media Setting
    MEDIA_URL = 'https://%s/media/users/'%(AWS_S3_CUSTOM_DOMAIN)
    DEFAULT_FILE_STORAGE = '내프로젝트명.asset_storanges.MediaStorage'

    3. asset_storanges.py 생성

    더보기
    from storages.backends.s3boto3 import S3Boto3Storage

     

    class MediaStorage(S3Boto3Storage):
    location = 'media/users'   # S3 주소를 지정 할 수 있다. (ex. s3주소/media/users/example.jpg)
    file_overwrite = False
     

     

    class StaticStorage(S3Boto3Storage):
    location = 'static'
    file_overwrite = False

     - !!! python manage.py collectstatic 명령어를 통해 static파일을 s3에 올려주는 작업을 하자(s3에 정적 파일을 볼 수 있다.)

     

    4.models.py 작성

    class User(AbstractBaseUser):
    	image = models.ImageField('이미지', default=DEFAULT_IMG,editable=True,null=True, blank = True, upload_to=rename_imgaefile)

    - default: 처음 아이디 생성시 가지고 있는 이미지

    - upload_to: 이미지 생성시 파일명을 재정의 하는 부분

    # 유저 이미지 생성시 이름 변경 함수
    def rename_imgaefile(instance, filename):
        ext = filename.split('.')[-1] # 확장자
        name = filename.split('.')[0] # 이름
        
        if instance:
            filename = '{}_{}.{}'.format(name,instance, ext)
        else:
            filename = '{}.{}'.format(name, ext)
        return filename

     

    5. view.py 작성

     def put(self, request, *args, **kwargs):
                user = request.user
                data = request.data
                serializer = UserInfoSerializer(user, data=data, partial =True)
                if serializer.is_valid(raise_exception = True):
                   serializer.save()
                   return Response(serializer.data, status = status.HTTP_200_OK)

    - 내 경우 이미지를 PUT method를 이용하였다.

     

    6. serializers.py 작성

    from rest_framework import serializers
    class UserInfoSerializer(serializers.ModelSerializer):
        image = serializers.ImageField(use_url=True)
        
        class Meta:
            model = User
            fields = '__all__'

    - image필드를 선언했지만 serializer로 선언을 해준 뒤 use_url=True로 설정을 해줘야 한다.

     


    Nginx 설정

    server {
    		....
            location /static/ {
                alias   https://{bucket_name}.s3.{aws_region}.amazonaws.com/static/;
            }
    
            location /media/ {
                alias   https://{bucket_name}.s3.{aws_region}.amazonaws.com/media/user/;
            }
     }

    - buckt_name : 내 S3 버켓 이름

    - aws_region: 내 S3 버켓 리젼


    이렇게 설정해주면 모든것이 끝이고 정적 파일도 육안으로 잘보이고 업로드도 바로 돼는 것을 확인 할 수 있다.

    아직도 갈길은 멀고 할일은 많고 배울것도 많다. 열심히 하자

    모두들 화이팅!!!

     

     

     

     

     

    Ref.

    https://velog.io/@gogimon/Django-s3-boto3

     

    Django - s3를 사용한 이미지 업로드 (feat.boto3)

    django boto3 file upload to s3

    velog.io

    [Django] AWS S3와 연동하기

    https://blog.siner.io/2019/07/17/django-aws-s3/

    https://naon.me/posts/til70

    https://zeallat.wordpress.com/2017/05/24/elb-django-rest-framework-s3-image-upload-%ED%95%98%EA%B8%B0/

    https://velog.io/@hwang-eunji/aws-s3-%EB%AF%B8%EB%94%94%EC%96%B4-%EC%84%9C%EB%B2%84-%EC%84%A4%EC%A0%95-django-%EC%84%A4%EC%A0%95

     

     

     

    - 어떤 문제를 해결하기위해 검색하고 블로그에 작성한 글입니다. 부족한점이 많지만 틀린점이나 부족한점이 있다면 말씀해주시면 감사하겠습니다. 

    댓글

Designed by Tistory.