DRF에서 multipart/form-data이미지 받아서 저장하기

정훈·2023년 7월 19일
0
post-thumbnail

django/DRF 이미지 업로드 예시를 찾아보면 이미지 저장에 대한 설명이 admin 페이지를 이용한 업로드 예시만 나와서 삽질한 저처럼 구현하고자 하는 분들을 위해 글을 남겨 놓으려고 합니다.

제가 구현하고자 했던 기능은 간단하게 이미지를 저장을 하는 기능을 만들고자 했습니다. 여기서 조건은 DRF에서 제공하는 테스트 웹페이지에서 업로드하고 파일 이름을 코드내에서 수정해서 저장이 되어야한다.

DRF에서 제공하는 테스트 웹페이지 예시
DRF에서 제공하는 테스트 웹페이지

일단은 manage.py가 있는 폴더에 media폴더를 생성해 줍니다.

이제 cmd창에서 manage.py가 있는 경로에서 >> python manage.py startapp photos라고 프로젝트를 하나 만들어 주겠습니다.

setting.py파일을 수정해줘야 합니다. INSTALLED_APPS라는 곳에 photos.apps.PhotosConfig을 등록해주고 MEDIA_URLMEDIA_ROOT를 선언해주시면 됩니다.


MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

INSTALLED_APPS = [
				.
                .
                .
    'photos.apps.PhotosConfig',
]

그 다음으로는 models.py에 모델을 만들어 주겠습니다.

from django.db import models

class Photo(models.Model):
    title = models.CharField(max_length=50)
    image = models.ImageField(upload_to="images")
    user_id = models.ForeignKey("users.User", on_delete=models.CASCADE, null = True, related_name= 'photo_user_id')
    update_time = models.DateTimeField(auto_now_add=True)

user_id는 어떤 유저가 올렸는지 표현하기 위해서 추가한 컬럼이니 빼셔도 상관 없습니다.
이제 모델을 적용하기 위해서 다시 cmd 창에
python manage.py makemigrationspython manage.py migrate를 입력해줍니다.
모델을 생성한 다음엔 serializers.py를 생성해줍니다.
serializer가 궁금하신분들을 위해 설명링크 달아드립니다.

from rest_framework import serializers
from .models import Photo

class PhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Photo
        fields = ('id', 'title', 'image', 'user_id', 'update_time')

이제 views.py에 코드를 구현해 주면 끝입니다.

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

import datetime

from .serializers import PhotoSerializer
from .models import Photo
# Create your views here.

class PhotoViewSet(APIView):
    queryset = Photo.objects.all()
    serializer_class = PhotoSerializer
    
    def get(self, request, **kwargs):
        photo_queryset = Photo.objects.all() #모든 Photo의 정보를 불러온다.
        photo_queryset_serializer = PhotoSerializer(photo_queryset, many=True)
        return Response(photo_queryset_serializer.data, status=status.HTTP_200_OK)
    
    def post(self, request, **kwargs):
        data = request.data.copy()
        
        now = datetime.datetime.now()
        
        data['image'].name = now.strftime('%Y-%m-%d %H:%M:%S')+'.png'
        
        photo_serializer = PhotoSerializer(data = data)
        if(photo_serializer.is_valid()):
            photo_serializer.save()
            return Response(photo_serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response("invalid request", status=status.HTTP_400_BAD_REQUEST)

간단한 코드 설명을 해드리 자면
GET 요청을 구현한 부분은 데이터베이스에 저장된 전체 튜플들을 확인할 수 있습니다.

POST요청을 하면 이미지를 확인하고 이미지 이름을 이미지에 저장하는 현재날짜와 시간을 이름으로 바꿔서 등록해줍니다.

이제 마지막으로 urls에 등록하면 끝입니다.

from photos.views import PhotoViewSet

urlpatterns = [
					.
                    .
                    .
    path('photos/', PhotoViewSet.as_view()),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

http://127.0.0.1:8000/photos/에 접속해보면

제가 테스트 했던 튜플들이 json형태로 보이는 것을 확인해 볼 수 있습니다.

이제 간단한 항목들을 입력하고 이미지를 선택해주고 POST를 눌러주면

추가된 항목을 확인해 볼 수 있습니다.
추가로 image에 있는 링크를 들어가 본다면 제가 선택한 사진을 확인해 볼 수 있습니다.

profile
누군가에게 빛이 되길...

3개의 댓글

comment-user-thumbnail
2023년 7월 19일

글 잘 봤습니다, 많은 도움이 되었습니다.

1개의 답글
comment-user-thumbnail
2024년 10월 31일

감사합니다!

답글 달기