DRF에서는 하나의 클래스에 관련한 뷰들의 집합을 합칠 수 있도록 해준다. 이것을 View Set이라고 부른다. 다른 프레임워크에서는 비슷한 개념을 'Resources'나 'Controllers'라고 부른다. (MVC의 C)
뷰 셋은 단순하게 보면 클래스 기반의 뷰 중에 하나인데 .get()이나 .post() 대신 .list()나 .create()같은 메서드 핸들러를 사용한다. View Set의 메서드 핸들러는 .as_view() 메서드를 사용하여 뷰를 종료하는 시점에 해당 작업에만 동작한다. 보통은 urls.py의 viewset에 일일이 view를 등록하기 보다는, 라우터 클래스로 view set을 등록하고 이 라우터가 자동으로 url을 결정해준다.
1. View Set
먼저 일반적인 viewset을 import해서 진행하는 방식을 소개해본다. 이후에 더 짧은 세 줄짜리 코드로도 할 수 있는 작업이지만, 긴 코드를 보면 무슨 동작을 하는지 이해하기가 편하다.
...
from django.shortcuts import get_object_or_404
from rest_framework import viewsets
class ArticleViewSet (viewsets.ViewSet):
#이걸 이용하면 list, retrieve, create, update, partial update, destory function을 다 직접 만들어야 함.
def list(self, request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def create(self, request):
serializer = ArticleSerializer(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)
def retrieve(self, request, pk=None):
queryset = Article.objects.all()
article = get_object_or_404(queryset, pk = pk)
serializer = ArticleSerializer(article)
return Response(serializer.data)
def update(self, request, pk= None):
article = Article.objects.get(pk = pk)
serializer = ArticleSerializer(article, data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST)
destroy나 partial update 함수는 만들지 않았지만 대략 이런 식으로 흘러간다. 전에 작성한 클래스 기반 뷰와 코드는 대부분 비슷하다. 다만 언급한 대로 함수 이름은 list, create, retrieve 등으로 해서 post, put, delete, get 은 사용하지 않는다.
이 때 urls.py에는 다음과 같이 작성해주면 된다.
from .views import ArticleViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('article', ArticleViewSet, basename='article')
urlpatterns = [
path('viewset/', include(router.urls))
]
여기까지 해주면 전에 진행했던 것과 비슷하게 http://127.0.0.1:8000/viewset/article/ 을 통해서 전체 article들을 확인할 수도 있고, http://127.0.0.1:8000/viewset/article/1/ 을 통해 디테일 페이지 처럼 구현하거나 update 혹은 destroy(예제에서는 함수를 생성하지 않아서 버튼이 없을 것이다) 할 수도 있다.
2. Generic View Set
이렇게만 해도 일반 클래스 기반 뷰보다 코드가 짧아지는데, Generic View Set으로 더 간단하게 이 모든 기능을 구현할 수도 있다. 이번에는 실제 함수들을 아예 작성하지 않아도 된다. 전부 제공되기 때문이다. 클래스 이름은 그대로 ArticleViewSet으로 두고 코드만 살짝 바꾸면 된다.
class ArticleViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin):
#mixins.ListModelMixin만 추가하면 되고 def list 필요 없음
serializer_class = ArticleSerializer
queryset = Article.objects.all()
나는 모든 기능을 구현하고 싶어서 ListModelMixin 부터 DestroyModelMixin까지 추가해줬다. 이렇게 세줄의 코드로 views.py는 마무리한다. urls.py에는 다음과 같이 추가해준다.
...
urlpatterns = [
...
path('viewset/<int:pk>/', include(router.urls))
]
이렇게 해주면 아까와 같이 http://127.0.0.1:8000/viewset/article/1/ 에서 GET, PUT, DELETE가 다 가능하다.
3. Model View Set
model view set은 generic view set을 상속받아 만드는 것으로 여러 mixin 클래스를 별도로 추가해주지 않고도 이용할 수 있다. Model View Set으로 사용할 수 있는 동작은 .list(), .retrieve(), .create(), .update(), .partial_update(), .destroy() 이다. 코드는 다음과 같다.
class ArticleViewSet(viewsets.ModelViewSet):
serializer_class = ArticleSerializer
queryset = Article.objects.all()
이렇게만 작성해주면 우리가 배웠던 모든 내용들을 손쉽게 할 수 있다.
여기까지 Django REST Framework 기초를 다뤄보았다. 대략적인 감은 잡히는데 아무래도 추가적으로 배워야 할 내용이 많을 것 같다.
'TIL > Python | Django' 카테고리의 다른 글
2021.8.24 TIL : [Python] 웹 크롤러 - 1 (0) | 2021.08.24 |
---|---|
2021.8.23 TIL : [Python] 기초 문법9 - super() (2) | 2021.08.23 |
2021.8.7 TIL : [Django] DRF 3 - authentication (0) | 2021.08.07 |
2021.8.6 TIL : [Django] DRF 2 - 클래스기반 api / 제네릭 클래스 기반(Generic Class-based) api (0) | 2021.08.06 |
2021.8.5 TIL : [Django] DRF(Django Rest Framework) 1 - 함수기반 api (0) | 2021.08.06 |
댓글