Server/Django

[Django] upload multiple image file in one model


한 모델에 여러 이미지 파일을 업로드 해야 할 때


Meet 이라는 모델이 있고, 그 모델 하나에 여러 이미지 파일이 들어갈 수 있는 상황이라고 했을 때,

어떻게 구현해야 할까?

 

쉽게 생각하자면, 댓글과 다를 것이 없다. 댓글 또한 one to many 모델이기 때문이다. 단지

댓글은 텍스트 데이터를 가지고 있는 것이고, 이미지 파일은 이미지 데이터를 가지고 있는 차이가 있을 뿐이다.

 

따라서 같은 방식으로 구현을 해주면 된다.

 

모델의 객체값을 ForeignKey로 가지고 있는 Images 라는 모델을 만들었다.

#models.py
class Meet(models.Model):
    pair = models.ForeignKey(Pair, blank=False, null=False, on_delete=models.CASCADE)
    author = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE)
    ...
    
class Images(models.Model):
    meet = models.ForeignKey(Meet, blank=False, null=False, on_delete=models.CASCADE)
    photo = ProcessedImageField(
        upload_to = 'meet_images',                    # 저장 위치
        processors = [ResizeToFill(80, 80)], # 사이즈 조정
        format = 'JPEG',                    # 최종 저장 포맷
        options = {'quality': 60},
        null=True) 

 

벌써 데이터를 저장할 준비가 끝났다! 이후 모델을 갱신해주자

$ python3 manage.py makemigrations & python3 manage.py migrate

 

그럼 이제 안드로이드에서 Multipart 형식으로 데이터를 넘길 때, 이를 받을 방법이 필요하다.

그런데 이 데이터는 리스트 형식으로 올 것이고(List<MultipartBody.Part>, 그렇다면 리스트 형식의 Multipart request를 받을 방법이 필요하다.

 

이는 아래와 같이 구현하였다.

#views.py
def create(self, request, *args, **kwargs):
	''' 중략 '''

    
    meet = serializer.save()

    image_list = request.FILES.getlist('image_path')
    for item in image_list: 
        images = Images.objects.create(meet=meet, photo=item)
        images.save()

    return Response(serializer.data)

아래 부분은 image_list 부분을 로그로 찍어보았을 때의 모습이다.

[<InMemoryUploadedFile: Screenshot_20191201-141758_NAVER.jpg (multipart/form-data)>,
<InMemoryUploadedFile: Screenshot_20191201-141758_NAVER.jpg (multipart/form-data)>]

InMemoryUploadedFile 객체의 배열로 구성되어 있음을 볼 수 있다.

이는 클래스명 그대로 메모리에 업로드된 파일 객체를 나타내는 클래스다. Ref)

 

지난 글인 [Server/Django] - [Django] AWS S3와 연동하기에 이어서 제대로 진행했다면,

S3에 해당 이미지 파일이 제대로 생성되어 있을 것이며, admin에 해당 Images 모델 등록 시

admin 페이지에서도 볼 수 있을 것이다.