CBV
class <클래스이름>(APIView):
def <내가 필요로 하는 HTTP Method>:
그 HTTP Method로 어떻게 처리할지는 직접 정의하기
views.py
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
# django rest framework -> router -> url
router = DefaultRouter()
router.register('post', views.PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
APIView
models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
serializer.py
from .models import Post
from rest_framework import serializers
# serializers의 Serializers는 Django의 Form과 유사한 역할을 한다
# serializer의 ModelSerializer는 Django의 ModelForm과 유사한 역할을 한다
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
# fields = '__all__'
fields = ('id', 'title', 'body') # id는 pk값
read_only_fields = ('title',) # 리스트도 가능하지만 튜플 사용을 권장함
views.py
# 데이터 처리 대상
from .models import Post
from .serializer import PostSerializer
# status에 따라 직접 Response를 처리할 것
from django.http import Http404 # Get object of 404 직접 구현
from rest_framework.response import Response
from rest_framework import status
# APIView를 상속받은 CBV
from rest_framework.views import APIView
# PostDetail 클래스의 get_object 메소드 대신 아래 코드를 써도 된다.
# from django.shortcuts import get_object_or_404
class PostList(APIView):
def get(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True) # 다수의 쿼리셋 객체 넘기기 (many=True)
return Response(serializer.data) # 직접 Response 리턴해주기 : serializer.data
def post(self, request):
serializer = PostSerializer(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) # Response(data, status)
# PostList 클래스와는 달리 pk값을 받음 (메소드에 pk인자)
class PostDetail(APIView):
# get_object_or_404를 구현해주는 helper function
def get_object(self, pk):
try:
return Post.objects.get(pk=pk)
except Post.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
post = self.get_object(pk)
# post = get_object_or_404(Post, pk)
serializer = PostSerializer(post)
return Response(serializer.data)
# 위 post 메소드와 비슷한 논리
def put(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post, 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):
post = self.get_object(pk)
post.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
urls.py
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
# Default Router 사용 X ==> API ROOT 없음
urlpatterns = [
# 127.0.0.1:8000/post == ListView
path('post/', views.PostList.as_view()),
# 127.0.0.1:8000/post/<pk> == DetailtView
path('post/<int:pk>', views.PostDetail.as_view),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Mixins
views.py
from .models import Post
from .serializer import PostSerializer
from rest_framework import mixins
from rest_framework import generics
class PostList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
# queryset과 serializer_class 는 generics.GenericAPIView에서 이미 선언된 클래스 변수이다.
queryset = Post.objects.all()
serializer_class = PostSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) # list는 mixins.ListModelMixin에서 이미 정의된 메소드이다.
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs) # create는 mixins.CreateModelMixin에서 이미 정의된 메소드이다.
class PostDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
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)
urls.py
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
# Default Router 사용 X ==> API ROOT 없음
urlpatterns = [
# 127.0.0.1:8000/post == ListView
path('post/', views.PostList.as_view()),
# 127.0.0.1:8000/post/<pk> == DetailtView
path('post/<int:pk>', views.PostDetail.as_view),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Generic CBV
views.py
from .models import Post
from .serializer import PostSerializer
from rest_framework import generics
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
urls.py
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
# Default Router 사용 X ==> API ROOT 없음
urlpatterns = [
# 127.0.0.1:8000/post == ListView
path('post/', views.PostList.as_view()),
# 127.0.0.1:8000/post/<pk> == DetailtView
path('post/<int:pk>', views.PostDetail.as_view),
]
urlpatterns = format_suffix_patterns(urlpatterns)
APIView
views.py
# ReadOnlyModelViewSet
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
class PostViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `detail` actions.
"""
queryset = Post.objects.all()
serializer_class = PostSerializer
# ModelViewSet
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
# @action 처리
from rest_framework import renderers
from rest_framework.decorators import action
from django.http import HttpResponse
class PostViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = Post.objects.all()
serializer_class = PostSerializer
# 권한 설정
# permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
# @ + 함수 → decorator(장식자)
# @action : Custom API 만들기(임의로 View 설계)
# @action(method=['post'])
# Custom API의 Default Method는 GET 방식이지만, action의 format 인자로 지정 가능하다.
# renderer_classes는 Response를 어떤 형식으로 Rendering 시킬 것인가
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
return HttpResponse("얍")
urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
# django rest framework -> router -> url
router = DefaultRouter()
router.register('post', views.PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
참고 : django-rest-framework github
참고 : django-rest-framework documentation
'Server > django' 카테고리의 다른 글
[Django] Filtering & Search (0) | 2020.05.25 |
---|---|
[Django] Pagination (0) | 2020.05.25 |
[Django] JSON 직렬화 - Serializer (0) | 2020.04.28 |
[Django] REST Architecture (0) | 2020.04.28 |
[Django] JSON, Http Request & Method, Httpie (0) | 2020.04.23 |