시리얼라이저

·2023년 9월 20일
0

웹개발 종합

목록 보기
7/23
post-thumbnail

웹에 응답을 보낼 때는 정해진 형태 - 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 의 코드가 훨씬 간결해진 것을 볼 수 있다.

  • Article objects 가 여러 개이기 때문에 many=True 를 써줘야 오류가 나지 않는다.

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)
  • 시리얼라이즈를 사용하지 않는다면 request.POST.get() 을 통해 데이터를 하나하나 받아와야 하지만, 시리얼라이즈를 통해 데이터를 한꺼번에 받아와 저장해줄 수 있다. -> 코드가 간결해진다.
  • Response 에 대한 참고
  • 여기서 serializer 을 사용하지 않고 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)
profile
공부 중

0개의 댓글