ssung_데이터 엔지니어링/3주차_장고 활용한 API 서버 만들기

Django 활용하기(3)

ssungcohol 2023. 11. 1. 17:06

Serialize (직렬화)

  • 모델 인스턴스나 QuerySet과 같은 데이터를 JSON 형식의 파일로 변환하는 작업
  • 프로젝트에서 만든 모델로부터 뽑은 queryset, 즉 모델 인스턴스를 JSON으로 변환

Deserialize

JSON 형식의 데이터를 정의된 포맷에 맞추어 다시 모델 인스턴스로 변환하는 작업


serialize 만들기

  • serialize는 생성 시 유효성 검사를 통과한 data를 기반으로 저장(validated_data)
# polls_api/serializers.py

from rest_framework import serializers
# Question 모델 불러오기
from polls.models import Question

class QuestionSerializer(serializers.Serializer):
    # 필드 정의
    id = serialziers.IntegerField(read_only=True)
    question_text = serializers.CharField(max_length=200)
    pub_date = serializers.DateTimeField(read_only=True)
    
    def create(self, validated_data):
        return Question.objects.create(**validated_data)
    
    # instance = create를 통해 만든 data
    def update(self, instance, validated_data):
        # validated_data를 가지고 오는데 ('업데이트가 된 data', '업데이트되지 않았을 때의 data')
        instance.question_text = validated_data.get('question_text', instance.question_text)
        instance.save()
        return instance

serialize 간단화

  • 기존 대비 create, update method 작성을 해주지 않아도 가능
# polls_api/serializers.py

from rest_framework import serializers
from polls.models import Quesion

class QuestionSerializer(serializers.ModerSerializer):
    class Meta:
        model = Question
        fields = ['id','question_text', 'pub_data']

JSON 형식의 API 형식의 server 구현

 

# poll_api/views.py

from django.shortcuts import render
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view

# 정보 조회하기 (GET)

@api_view()  # @api_view() 괄호 안에 아무것도 입력을 안하면 GET
def question_list(request):
    questions = Question.objects.all()
    serializer = QuestionSerializer(questions, many = True)
    return Response(serializer.data)
    
==============================================================

# polls_api/urls.py

from django.urls import path
from .view import *

urlpatterns = [
    path('question/', question_list, name='question-list'),
]

==============================================================

# mysite/urls.py

from django.urls import include, path
from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/', include('polls.urls')),
    path('rest/', include('polls_api.urls')),
]

POST 구현

 

# poll_api/views.py

from django.shortcuts import render
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view

# post 구현

@api_view(['GET', 'POST'])  
def question_list(request):
    if request.method == 'GET':
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many = True)
        return Response(serializer.data)
        
    if request.method == 'POST':
        serializer = QuestionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

PUT, DELETE 구현

 

# polls_api/views.py

from django.shortcuts import get_object_or_404

@api_view(['GET', 'PUT', 'DELETE'])
def question_detail(request, id):
    question = get_object_or_404(Question, pk=id)
    
    
    if request.method == 'GET':
        serializer = QuestionSerializer(question)
        return Response(serializer.data)
        
    if request.method == 'POST':
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
            
    if request.method == 'DELETE':
        question.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
        
==================================================

# polls_api/urls.py

from django.urls import path
from .views import *

urlpatterns = [
    path('question/', question_list, name='question-list'),
    path('question/<int:id>/', question_detail, name='question-detail')
]

Method가 아닌 Class 기반 구현으로 변경

 

from rest_framework.view import APIView

class QuestionList(APIView):
    def get(self, request):
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many=True)
        return Response(serializer.data)
        
    def post(self, request):
        serializer = QuestionSerializer(data=request.data)
        if serializer.is_valid()
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        retrun Response(serializer.errors, status=status.HTTPS_400_BAD_REQUEST)
        
class QuestionDetail(APIView):
    def get(self, request, id):
        question = get_object_or_404(Question, pk=id)
        serializer = QuestionSerializer(question)
        return Response(serializer.data)
        
    def put(self, request, id):
        question = get_object_or_404(Question, pk=id)
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid()
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
            
    def delete(self, requeset, id):
        question = get_object_or_404(Question, pk=id)
        question.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
        
=========================================================

# polls_api/urls.py

from django.urls import path
from .views import *

urlpatterns = [
    path('question/', QuestionList.as_view(), name='question-list'),
    path('question/<int:id>/', QuestionDetail.as_view(), name='question-detail'),
]

Mixin 으로 간단화

 

# polls_api/views.py

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import mixins
from rest_framework import generics

class QuestionList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class QuestionDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
        
=====================================================

# polls_api/urls.py

from django.urls import path
from .views import *

urlpatterns = [
    path('question/', QuestionList.as_view(), name='question-list'),
    path('question/<int:pk>/', QuestionDetail.as_view(), name='question-detail'),
]

Generic으로 간단화

 

# polls_api/views.py

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import generics

class QuestionList(generics.ListCreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

class QuestionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
728x90

'ssung_데이터 엔지니어링 > 3주차_장고 활용한 API 서버 만들기' 카테고리의 다른 글

Django 활용하기(5)  (1) 2023.11.03
Django 활용하기(4)  (1) 2023.11.02
Django 활용하기(2)  (0) 2023.10.31
Django 활용하기(1)  (0) 2023.10.30