Posted by
Seoyoung Lee
on August 10, 2020 ·
6 mins read
ViewSet
ViewSet은 2개의 뷰를 만들어주는 보다 확장된 형태의 CBV(Class Based View)이다.
모든 CBV는 .as_view({'http_method': '처리할 멤버함수'})를 호출하여 해당 http_method를 지원하는 뷰 함수를 생성한다. 1개의 뷰 함수를 생성하므로, 하나의 URL만을 처리할 수 있다.
DRF에서는 ReadOnlyModelViewSet과 ModelViewSet의 2가지 뷰셋을 지원한다. 아래에서는 ModelViewSet에 대한 예시를 살펴본다.
우선 app을 만들고 migrate후, 모델과 이에 대한 Serializer를 만든다.
다음으로 ViewSet을 정의한다.
이렇게 만들어진 뷰 함수는 다른 FBV와 동일하게 URLConf에 매핑할 수 있다.
Router
기존에는 as_view()를 통해 각 request method마다 대응되는 함수를 연결시켜 주었다면 router는 단지 PostViewSet을 Router에 등록하기만 하면, 이를 알아서 연결해준다.
디폴트 매핑은 위와 같이 list route와 detail route가 있다.
Router에는 뷰셋만 등록할 수 있으며(뷰는 불가능) 하나의 Router에 다수의 뷰셋을 등록할 수 있다.
위의 urls.py를 아래와 같이 Router를 사용하도록 수정했다.
Router를 사용하면 더 이상 as_view()를 통해 단일 뷰를 뽑아낼 필요가 없다.
ViewSet에 API추가하기
디폴트 매핑의 경우, list route 에 대해서 2개, detail route 에 대해서 4개에 대해서 매핑을 해주게 된다. 여기서 추가적인 API를 만들어 매핑하는 방법이 있다.
ViewSet의 멤버함수로 추가 API를 구현한 후, decorator를 붙여주면 된다. 이때 URL은 Router가 알아서 결정한다.
@action decorator
위와 같이 action decorator를 import해주고 첫번째 인자로 detail, 두번째 인자로 methods를 지정한다.
detail이 True인 경우 pk값을 지정해주는 detail route에 등록이 되고, False인 경우에는 목록단위로 적용되는 list route에 등록이 된다. 이 때 detail의 값에 따라 Router가 URL을 결정하는 방법이 다르다.
methods인자에는 request method를 지정해줄 수 있다. 디폴트 값은 get이다.
아래 코드는 is_public값이 True인 레코드만 필터링하는 public_list와 특정 레코드의 is_public을 True로 수정하는 set_public을 정의했다.