django/DRF 이미지 업로드 예시를 찾아보면 이미지 저장에 대한 설명이 admin 페이지를 이용한 업로드 예시만 나와서 삽질한 저처럼 구현하고자 하는 분들을 위해 글을 남겨 놓으려고 합니다.
제가 구현하고자 했던 기능은 간단하게 이미지를 저장을 하는 기능을 만들고자 했습니다. 여기서 조건은 DRF에서 제공하는 테스트 웹페이지에서 업로드하고 파일 이름을 코드내에서 수정해서 저장이 되어야한다.
DRF에서 제공하는 테스트 웹페이지 예시
일단은 manage.py
가 있는 폴더에 media
폴더를 생성해 줍니다.
이제 cmd창에서 manage.py
가 있는 경로에서 >> python manage.py startapp photos
라고 프로젝트를 하나 만들어 주겠습니다.
setting.py
파일을 수정해줘야 합니다. INSTALLED_APPS
라는 곳에 photos.apps.PhotosConfig
을 등록해주고 MEDIA_URL
과 MEDIA_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 makemigrations
와 python 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에 있는 링크를 들어가 본다면 제가 선택한 사진을 확인해 볼 수 있습니다.
글 잘 봤습니다, 많은 도움이 되었습니다.