Notice
Recent Posts
Recent Comments
Link
오늘도 개발
Django Rest Framework 튜토리얼 따라하기 2. view 쉽게 작성하기 본문
1. DRF에서 제공하는 Request, Response, Status code
Request 오브젝트
django의 HttpRequest 오브젝트를 확장한 것.
좀 더 유연하게 데이터를 다룰 수 있는 data() 메서드를 제공한다.
# django의 HttpRequest에서 나온 오브젝트. POST 메서드의 form 데이터만 다룰 수 있다.
request.POST
# drf의 Request에서 나온 오브젝트. POST, PUT, PATCH 메서드까지 다룰 수 있다.
request.data
Response 오브젝트
클라이언트가 요청한 content type대로 데이터를 렌더링해준다.
return Response(data)
status codes
상태 코드를 더 정확하게 사용할 수 있게 숫자에 설명을 더한 identifier를 제공한다.
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2. DRF의 api view
아래 두 가지 방법을 사용하면 view에서 Request와 Response 오브젝트를 사용할 수 있다.
1. @api_view 데코레이터 추가
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
@api_view(['GET', 'POST'])
# format=None을 붙이고, urls.py에 설정을 추가하면 클라이언트 요청에 맞는 형식으로 데이터를 응답할 수 있다.
def snippet_list(request, format=None):
if request.method == "GET":
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
# Response 오브젝트를 사용할 수 있다.
return Response(serializer.data)
if request.method == "POST":
# @api_view를 사용하기 전 작성했던 아래 코드는 이제 명시할 필요가 없다.
# data = JSONParser().parse(request)
# 바로 request.data로 사용할 수 있다.
serializer = SnippetSerializer(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)
@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk, format=None):
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
elif request.method == "PUT":
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
2. APIView 클래스 상속
데코레이터보다 더 코드 반복을 줄일 수 있는 방법.
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
class SnippetList(APIView):
def get(self, request, format=None):
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = SnippetSerializer(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 SnippetDetail(APIView):
def get_object(self, pk):
try:
return Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Http404
def get(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
def put(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
3. DRF의 mixin 사용하기
mixin은 자주 사용하는 create, retrieve, update, delete 작업을 구현해둔 클래스이다.
mixin 클래스를 상속받으면 더 간단하게 view를 작성할 수 있다.
예를 들어 ListModelMixin은 여러 오브젝트를 응답하는 list 메서드를,
RetrieveModelMixin은 한 오브젝트를 응답하는 retrieve 메서드를 갖는다.
generics.GenericAPIView는 기본적인 APIView이다.
mixin 클래스를 사용할 때 함께 같이 사용해야 한다.
from rest_framework import mixins
from rest_framework import generics
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
class SnippetList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
# SnippetList에서 사용할 queryset과 serializer_class를 DRF에게 알려줌
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
'''
위의 코드는 아래 코드와 같은 일을 함
def get(self, request, format=None):
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)
'''
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
'''
def post(self, request, format=None):
serializer = SnippetSerializer(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 SnippetDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
'''
def get(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
'''
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
'''
def put(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
'''
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
'''
def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
'''
generic.GenericAPIView와 mixin을 합친 ListAPIView, RetrieveAPIView 등도 있다.
'웹 프로그래밍 > Django' 카테고리의 다른 글
| Django Rest Framework 튜토리얼 따라하기 4. Hyperlink API (0) | 2023.01.08 |
|---|---|
| Django Rest Framework 튜토리얼 따라하기 3. authentications and permissions (0) | 2023.01.08 |
| Django Rest Framework 튜토리얼 따라하기 1. Serialization (6) | 2023.01.07 |
| Django ORM 최적화 - select_related, prefetch_related (0) | 2022.08.05 |
| Django로 Unit Test해보기 (0) | 2022.08.05 |