게시물 추가 api를 만드는 도중에 이미지도 필수로 추가를 해야 되는 것을 깨닫았다. 나중에 까먹을 것을 대비해 노트를 하기로 했다.
게시물에 이미지를 첨부하려면 먼저 모델에 ImageField를 추가해야 한다. ImageField는 이미지 파일을 저장하고 업로드할 수 있는 필드다.
from django.db import models
from accounts.models import User
class Product(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
image = models.ImageField(upload_to='images/') # 이미지 필드 추가
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f"{self.id}: {self.title}"
설명:
upload_to='images/'를 통해 파일이 저장될 경로를 설정할 수 있다.이미지를 포함하는 데이터를 처리하기 위해 ModelSerializer를 설정한다. 이미지를 함께 처리하기 위해서는 해당 필드를 ProductSerializer에 포함해야 한다.
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__' # 모든 필드를 직렬화, 이미지 필드도 포함
설명:
이미지를 포함한 데이터를 처리하려면 POST 요청을 통해 파일을 함께 전송해야 한다. 뷰에서 이를 처리하는 방법은 다음과 같다.
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import Product
from .serializers import ProductSerializer
class ProductListView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
title = request.data.get("title")
content = request.data.get("content")
image = request.FILES.get("image") # 이미지 파일 처리
product = Product.objects.create(
title=title,
content=content,
image=image,
author=request.user
)
serializer = ProductSerializer(product)
return Response(serializer.data, status=201)
설명:
이미지를 게시물에 업로드한 후에는 템플릿에서 이미지를 출력할 수 있다. 업로드된 이미지의 URL을 사용해 이미지를 표시한다.
{% if product.image %}
<img src="{{ product.image.url }}" alt="{{ product.title }}">
{% endif %}
설명:
이미지 파일이 제대로 저장되고 서비스되기 위해서는 settings.py에서 미디어 파일 설정이 필요하다.
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
또한 urls.py 파일에서 미디어 파일을 제공할 수 있도록 설정해야 한다.
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# 다른 URL 패턴들
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
설명: