🙂 Serilaizer
Serialize: 모델 인스턴스나 QuerySet과 같은 데이터를 JSON으로 변환하는 과정
$ python manage.py startapp polls_api
polls_api 라는 새로운 app 생성
✔ polls_api/serializers.py
from rest_framework import serializers
from polls.models import Question
class QuestionSerializer(serializers.Serializer):
id = serializers.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)
def update(self, instance, validated_data):
instance.question_text = validated_data.get('question_text', instance.question_text)
instance.save()
return instance
🙂 Django Shell에서 Serializer 사용하기
✔ polls_api/serializers.py
from rest_framework import serializers
from polls.models import Question
class QuestionSerializer(serializers.Serializer):
id = serializers.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)
def update(self, instance, validated_data):
instance.question_text = validated_data.get('question_text', instance.question_text) + '[시리얼라이저에서 업데이트]'
instance.save()
return instance
✔ Django Shell
#Serialize
>>> from polls.models import Question
>>> from polls_api.serializers import QuestionSerializer
>>> q = Question.objects.first()
>>> q
<Question: 제목: 휴가를 어디서 보내고 싶으세요?, 날짜: 2023-02-05 18:52:59+09:00>
>>> serializer = QuestionSerializer(q)
>>> serializer.data
{'id': 1, 'question_text': '휴가를 어디서 보내고 싶으세요?', 'pub_date': '2023-02-05T18:52:59Z'}
>>> from rest_framework.renderers import JSONRenderer
>>> json_str = JSONRenderer().render(serializer.data)
>>> json_str
b'{"id":1,"question_text":"\xed\x9c\xb4\xea\xb0\x80\xeb\xa5\xbc \xec\x96\xb4\xeb\x94\x94\xec\x84\x9c \xeb\xb3\xb4\xeb\x82\xb4\xea\xb3\xa0 \xec\x8b\xb6\xec\x9c\xbc\xec\x84\xb8\xec\x9a\x94?","pub_date":"2023-02-05T18:52:59Z"}'
# Deserialize
>>> import json
>>> data = json.loads(json_str)
>>> data
{'id': 1, 'question_text': '휴가를 어디서 보내고 싶으세요?', 'pub_date': '2023-02-05T18:52:59Z'}
>>> serializer = QuestionSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.validated_data
OrderedDict([('question_text', '휴가를 어디서 보내고 싶으세요?')])
>>> new_question = serializer.save() # Create
>>> new_question
<Question: 제목: 휴가를 어디서 보내고 싶으세요?, 날짜: 2023-02-14 18:46:56.209215+00:00>
>>> data={'question_text': '제목수정'}
>>> serializer = QuestionSerializer(new_question, data=data)
>>> serializer.is_valid()
True
>>> serializer.save() # Update
<Question: 제목: 제목수정[시리얼라이저에서 업데이트], 날짜: 2023-04-25 13:15:05.852404+00:00>
#Validation이 통과하지 않는 경우
>>> long_text = "abcd"*300
>>> data = {'question_text':long_text}
>>> serializer = QuestionSerializer(data=data)
>>> serializer.is_valid()
False
>>> serializer.errors
{'question_text': [ErrorDetail(string='Ensure this field has no more than 200 characters.', code='max_length')]}
🙂 ModelSerializer
✔ polls_api/serializers.py
from rest_framework import serializers
from polls.models import Question
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['id','question_text', 'pub_date']
✔ Django Shell
>>> from polls_api.serializers import QuestionSerializer
>>> print(QuestionSerializer())
QuestionSerializer():
id = IntegerField(read_only=True)
question_text = CharField(max_length=200)
pub_date = DateTimeField(read_only=True)
>>> serializer = QuestionSerializer(data={'question_text':'모델시리얼라이저로 만들어 봅니다.'})
>>> serializer.is_valid()
True
>>> serializer.save()
<Question: 제목: 모델시리얼라이저로 만들어 봅니다., 날짜: 2023-02-14 19:41:081444+00:00>
🙂 HTTP 요청 메서드
CRUD 기능을 구현
HTTP는 요청 메서드를 정의하여, 주어진 리소스에 수행하길 원하는 행동을 나타낸다.
✔ POST (Create)
특정 리소스에 엔티티를 제출할 때 사용.
✔ GET (Read)
특정 리소스의 표시를 요청.
✔ PUT (Update)
목적 리소스의 모든 현재 표시를 요청 payload로 변경
✔ DELETE (Delete)
특정 리소스를 삭제
🙂 GET
✔ polls_api/views.py
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view
@api_view()
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 .views import *
urlpatterns = [
path('question/', question_list, name='question-list')
]
✔ mysite/views.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
✔ polls_api/views.py
from rest_framework.decorators import api_view
from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.response import Response
from rest_framework import status
@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 == 'PUT':
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')
]
🙂 Class 기반의 뷰(Views)
✔ polls_api/views.py
from rest_framework.views 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)
return Response(serializer.errors, status=status.HTTP_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, request, 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 API View
✔ 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'데이터엔지니어링' 카테고리의 다른 글
| [3주차] 장고 활용한 API서버 만들기 (5) (0) | 2024.04.13 |
|---|---|
| [3주차] 장고 활용한 API서버 만들기 (4) (0) | 2024.04.11 |
| [3주차] 장고 활용한 API서버 만들기 (2) (0) | 2024.04.09 |
| [3주차] 장고 활용한 API서버 만들기 (1) (0) | 2024.04.08 |
| [2주차] 파이썬으로 웹다루기 (5) (0) | 2024.04.05 |