웹에 응답을 보낼 때는 정해진 형태 - json - 으로 보내야 한다. 해서 저번 프로젝트를 할 때에는 context 에 딕셔너리 형태의 데이터를 보냈는데, 모든 데이터를 일일히 그렇게 보내기는 굉장히 번거롭고 시간도 많이 걸린다.
그런 의미에서 등장한 것이 시리얼라이저 라는 도구이다. 시리얼라이저는 자동으로 데이터를 json 형태로 변환시켜 response 해주기 때문에 우리가 데이터를 수작업으로 바꿀 필요가 없다.
시리얼라이저가 없을 때
@api_view(["GET", "POST"])
def test(request):
articles = Article.objects.all()
article = articles[0]
context = {
'title': article.title,
'content': article.content,
'created_at': article.created_at,
'updated_at': article.updated_at,
}
return Response(context)
시리얼라이저를 사용할 때
serializers.py
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
# Article 모델을 사용할 것이고, 모든 필드를 불러온다
model = Article
fields = "__all__"
views.py
@api_view(["GET", "POST"])
def test(request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
시리얼라이저가 알아서 모델 필드를 json 형태로 바꿔주기 때문에 views.py 의 코드가 훨씬 간결해진 것을 볼 수 있다.
POST 로 새로운 오브젝트를 생성하고 싶을 때에도 시리얼라이저를 활용해줄 수 있다.
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer
# Create your views here.
@api_view(["GET", "POST"])
def test(request):
if request.method == "GET":
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
elif request.method == "POST":
# json 형태로 데이터를 받아온다
serializer = ArticleSerializer(data=request.data)
# 데이터 유효성 검사를 한 뒤
if serializer.is_valid():
# 그대로 저장
serializer.save()
# Response 로 return 해주기 때문에 serializer 의 data 를 사용한다는 것을 알려주어야 한다.
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
# 오류가 났다면 오류코드와 오류 메세지를 리턴한다.
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response(article)
을 해주면 데이터가 json 이 아니라는 오류가 난다.여기까지 article 을 받아 보여주는 과정이었고, 수정이나 삭제는 특정 오브젝트의 아이디가 필요하기 때문에 url 이 달라진다.
우선 url 수정을 통해 특정 article 의 아이디를 받아올 수 있도록 한다.
urls.py
from django.contrib import admin
from django.urls import path, include
from articles import views
urlpatterns = [
path("index/", views.test, name="test"),
path("<int:id>/", views.article_view, name="article-view"),
]
수정을 한 뒤에는 views.py 에 article_view 메소드를 만들어 특정 article 을 받아오는 작업을 수행한다. 이때 해당 id 의 article 이 존재하지 않으면 404 에러를 리턴하도록 Article.objects.get(id=id)
대신 from rest_framework.generics import get_object_or_404
를 통해 get_object_or_404(Article, id=id)
를 사용한다.
views.py
@api_view(["GET", "PUT", "DELETE"])
def article_view(request, id):
if request.method == "GET":
article = get_object_or_404(Article, id=id)
serializer = ArticleSerializer(article)
return Response(serializer.data)
article 수정은 PUT 방식으로 할 것이므로 아래에 elif 를 통해 PUT 을 넣어준 뒤 마찬가지로 get_object_or_404(Article, id=id)
를 통해 해당 id의 aricle 을 받아온다.
이 다음 ArticleSerializer 의 애트리뷰트로 article 과 request.data 를 쓰면 시리얼라이저가 알아서 뒤쪽의 데이터를 article 의 데이터로 넣어준다.
data=
을 통해 데이터를 명시하는 것을 잊지 말도록 하자그 다음은 위에 썼던 POST 방식과 똑같이 유효성 검사를 한 뒤 저장해주면 된다.
@api_view(["GET", "PUT", "DELETE"])
def article_view(request, id):
if request.method == "GET":
article = get_object_or_404(Article, id=id)
serializer = ArticleSerializer(article)
return Response(serializer.data)
elif request.method == "PUT":
article = get_object_or_404(Article, id=id)
serializer = ArticleSerializer(article, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)