본문 바로가기

졸업 프로젝트

이미지 파일 다루기(AWS S3 이용)

# S3 설정하

 

프론트에서 이미지를 서버에서 불러오도록 요청했다.

AWS S3에 이미지를 넣어두고 게시글 객체마다 각기 다른 이미지를 불러올 것이다.

S3

일단 버킷을 하나 만들었다.

 

사용할 이미지 업로드하기

 

버킷>내 버킷>권한>버킷정책 편집>정책 생성기 에서 권한을 편집해준다.

Actions는 GETObject만 설정해주었다.

 

CORS 설정도 해주기.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

 

이제 객체 URL로 들어가면 이미지가 잘 보인다!

객체 url들어가기

 


# API 수정하기

 

저 9개의 이미지 객체 중 겹치지 않게 랜덤으로 보여주어야 한다!

먼저 게시글 모델에 이미지 URL이 들어갈 필드를 하나 추가했다. model을 건드리기는 싫었지만..어쩔 수 없었음

class Post(models.Model):
    
    level_list = [
        (1, 1),
        (2, 2),
        (3, 3),
        (4, 4),
        (5, 5)
    ]

    group_list = [
        ('진로', '진로'),
        ('연애', '연애'),
        ('가족/친구', '가족/친구'),
        ('기타', '기타')
    ]
    image_list = [ # (DB에 저장되는 값, 사용자에게 보여지는 값)
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL1.jpeg', 1),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL2.jpeg', 2),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL3.jpeg', 3),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL4.jpeg', 4),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL5.jpeg', 5),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL6.jpeg', 6),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL7.jpeg', 7),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL8.jpeg', 8),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL9.jpeg', 9)

    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    author = models.ForeignKey(User, null=True, on_delete=models.CASCADE)  # 게시글 작성자
    level=models.IntegerField(choices=level_list) # 심각도
    title = models.CharField(max_length=20)
    tag = models.CharField(max_length=8)
    group = models.CharField(max_length=16, choices=group_list) # 게시판 유형
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    image = models.CharField(max_length=128, choices=image_list, default = 'https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL1.jpeg') # 이미지 객체 URL

    def __str__(self):
        return f'[{self.id}]{self.title} :: {self.author}'

 

일단 내가 생각하기에, 가져와야 하는 것은

1. 유저별 게시글 count() 값 가져오기.

2. % 연산자로 순서대로 저 image_list의 값을 가져와서 저장.

 

일단 count()는 내가 따로..필드를 만들어두지 않았기에 view에서 코드를 작성해 가져왔다.

이럴줄 알았으면 User Model에 따로 필드를 만들어둘걸...후회했다. 다음에는 많이 사용될 것 같으면 게시글을 Count하는 필드를 꼭 추가해야겠음.

class PostViewSet(viewsets.ModelViewSet):
    queryset=Post.objects.all()
    serializer_class=PostSerializer

    permission_classes = [IsAuthenticated, AuthenticatedOnly]
    pagination_class = LargeResultsSetPagination
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["group"]


    def perform_create(self, serializer):
        # 이미지 저장을 위한 것
        image_list = [ # (DB에 저장되는 값, 사용자에게 보여지는 값)
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL1.jpeg', 1),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL2.jpeg', 2),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL3.jpeg', 3),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL4.jpeg', 4),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL5.jpeg', 5),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL6.jpeg', 6),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL7.jpeg', 7),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL8.jpeg', 8),
        ('https://dislodged.s3.ap-northeast-2.amazonaws.com/dislodged_image/DL9.jpeg', 9)

    ]
        total_posts = (Post.objects.filter(author=self.request.user).count())%9
        image_url = image_list[total_posts][0]

        serializer.save(author = self.request.user, image=image_url)

이렇게 이미지 리스트를 만든 후 image_url에 각자 해당하는 값을 가져와서 저장한다.

그리고 save()와 동시에 image라는 이름으로 객체를 serializer에 저장!

 

class PostSerializer(serializers.ModelSerializer):
    author_id = serializers.ReadOnlyField(source='author.id')
    author = serializers.ReadOnlyField(source='author.nickname')
    comment = CommentSerializer(many=True, source='comments', read_only=True) #source=model의 related_name 명시해야 보임
    
    image_url = serializers.ReadOnlyField(source='image') # 이미지

    class Meta:
        model = Post
        fields = ['id', 'author_id', 'author','image_url','level','title','tag','group','content','created_at','updated_at','comment']

ReadOnlyFiled로 받아온 image를 저장 후 변환해주기.

 

image_url 주목

작성할 때마다 image가 달라지는 것을 볼 수 있다.

 


# 회고

 

근데 저거는 기존에 있던 게시글에는 사진이 고정이라...다시 DB 밀고 만들어야할듯🥲

요금 정책 바뀌어서 이 단계가 약간 귀찮아졌다.