- [ISSUE] gernerics view, DestroyAPIView 적용2023년 05월 05일
- 조별하
- 작성자
- 2023.05.05.:09
[22.11.20] Try to apply generics DestroyAPIView
Generics View를 사용하지 않는 이유
✔️ DRF로 서버단을 rest_framework가 지원해주는 generics View를 사용하지 않고 APIView만을 이용하여 프로젝트를 진행하기로 결정하였다.
✔️ 그렇게 결정한 이유는 generics 한 View를 사용하면 코드가 간결해지고 개발하기 편리해지긴 하지만 팀 프로젝트를 진행하며 그렇게 간결해지고 작동되는 로직을 파악하지 않고 무분별하게 사용하는 것을 우려하여 처음에는 자유롭게 customizing이 가능한 APIView를 사용하기로 했다.
APIView로 작성된 Bulk Delete
✔️ 항목을 다중으로 삭제하기 위한 기능 개발을 위해 클라이언트 단에서 선택한 항목의 id(식별자)를 리스트로 전달하여 서버 단에서 받아 그 항목들을 모두 삭제하는 로직을 개발하였다.
클라이언트 단
function setFetchData(method, body){ /* Fetch data 셋팅 */ let csrftoken = getCookie('csrftoken'); const data = { method: method, headers: { 'content-type': 'application/json', 'X-CSRFToken' : csrftoken, }, body: JSON.stringify(body) } return data } function bulkDelete() { /* 벌크 삭제 이벤트 */ const data = setFetchData("DELETE", { pk_ids: selected_articles, // [1, 2, 3, 4, 5] }) fetch(`/api/sites/bulk`, data) .then(response => { let status = response.status if(status == 200) alert('삭제에 성공하였습니다.') }) .then(() => getSiteList()) .then(() => changeSelected()) .catch(error => console.log(error)) }
서버 단
# urls.py path('sites/bulk', SiteBulkAPIView.as_view()) # views.py class SiteBulkAPIView(APIView): """ 벌크 항목 삭제 api """ def delete(self, request): pk_ids: list = self.request.data.get('pk_ids') sites = Site.objects.filter(id__in=pk_ids) for site in sites: site.delete() return Response({'msg': 'Deleted successfully'}, status=status.HTTP_200_OK)
APIView
# 상속받은 APIVIEW class APIView(View): # The following policies may be set at either globally, or per-view. renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES ... # APIView가 상속받은 View class View: """ Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking. """ http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
✔️ 상속받은 APIView가 어떻게 HTTP 메소드에 따라 어떻게 작성한 내부 메서드로 들어와 처리가 될 수 있는지 APIView를 타고 들어가 부모 클래스인 View까지 타고 들어가 코드를 확인해 보니 View클래스에서 http 매소드 명에 따라 작성한 내부 메서드로 핸들링해주고 있었다.
DestroyAPIView로 delete처리 적용
✔️ Delete 처리를할 때 rest_framework의 DestroyAPIView로 처리한다고 공식문서를 확인하여 이를 이용하여 로직을 변경해보려 했다.
✔️ 하지만 DestroyAPiView는 하나의 id(식별자) 값만 path파라미터로 받아 처리를 해주는 클래스이기 때문에 bulk처리에는 적합하지 않았다. 그래서 bulk처리가 아닌 단일 삭제 처리 기능에서 DestroyAPIView를 적용해 보았다.
출처 : DRF 공식문서클라이언트 단
function deleteSite() { const data = setFetchData('DELETE', '') fetch(`/api/sites/${site.id}`, data) .then(response => { const status = response.status if (status === 200) { console.log('삭제 완료했습니다.') } else if (status === 404) { console.log('해당 항목이 존재하지 않습니다.') } return response.json() }) .catch(error => console.log('Error:', error)) }
서버 단
# urls.py path('sites/<int:pk>', SiteDetailAPIView.as_view()), # views.py class SiteDetailAPIView(DestroyAPIView): """ 항목 단일 삭제 api """ queryset = Site.objects.all() serializer_class = SiteSerializer
✔️ 위 와 같이 작성 후 삭제를 시도하면 삭제되는 코드를 작성하지 않았지만 DestroyAPIView를 상속받은 것 만으로 전달받은 pk값을 인식하여 해당하는 데이터를 처리해준다.
DestroyAPIView
# DestroyAPIView class DestroyAPIView(mixins.DestroyModelMixin, GenericAPIView): """ Concrete view for deleting a model instance. """ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) # mixins.DestroyModelMixin class DestroyModelMixin: """ Destroy a model instance. """ def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) def perform_destroy(self, instance): instance.delete()
코드 작성을 하지 않고 처리가 되는 과정을 확인해 보기 위해 상속받은 DestroyAPIView를 확인해 보았다. DestroyAPIView가 또 다른 두 개의 클래스 mixins.DestroyModelMixin와 GenericAPIView를 상속받고 있는데 삭제 처리가 작성되어 있는 DestroyModelMixin 클래스를 타고 들어가 확인해 보면 destroy내부 함수에 perform_destroy로 해당 인스턴스를 삭제하는 코드가 작성된 것을 확인할 수 있다. 즉, 우리는 이 클래스를 상속받아 우리가 작성해야 하는 코드대신 그 안에서 작성된 코드가 실행되어 처리된다는 것을 알 수 있다.
'ISSUE' 카테고리의 다른 글
[ISSUE] REST API GET방식에서 POST로의 변경 (0) 2023.04.19 다음글이전글이전 글이 없습니다.댓글