[Django] GenericView 동작방법
Python Class-based View
GenericView
를 쓰고 있는 class 에 delete
메소드가 있었는데, delete 요청을 보내면 어떻게 해당 함수를 매핑하는지가 궁금했다. 왜냐하면 Viewsets - Django REST framework 에서는 아래 항목을 지원한다고 적혀있기 떄문이다.
class UserViewSet(viewsets.ViewSet):
"""
Example empty viewset demonstrating the standard
actions that will be handled by a router class.
If you're using format suffixes, make sure to also include
the `format=None` keyword argument for each action.
"""
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
어떻게 delete
함수가 매핑되는 것일까? 먼저 urls.py
에서 해당 ViewSet을 router 에 의해 url이 매핑되는 것을 확인했다. 그리고 router.urls
로 url 매핑된 것을 찾았다.
<URLPattern '^abc/?$' [name='abc-list']>,
<URLPattern '^abc/confirm/?$' [name='abc-confirm']>,
<URLPattern '^abc/detail/?$' [name='abc-detail-info']>,
<URLPattern '^abc/recover/?$' [name='abc-recover']>,
<URLPattern '^abc/verify/?$' [name='abc-verify']>,
<URLPattern '^abc/(?P<pk>[^/.]+)/?$' [name='abc-detail']>,
하지만 이렇게 보면 custom한 엔드포인트와, —list, —detail 엔드포인트만 보여주지 어떤 method 에 매핑되는지는 적혀있지 않다. 따라서 ViewSet 인스턴스 자체를 가져와서 확인해보기로 했다.
에러가 뜬다. as_view()
는 {‘get’: ‘;list’} 처럼 어떤 메서드로 요청되었을 때 어떤 함수를 실행하라 라는 파라미터를 주고 view를 만드는 함수이기 떄문이다.
그냥 ViewSet 자체를 보면 어떻게 나오는지 실행해봤다.
유의미한 것이 보였다! ViewSet자체에서 delete 함수를 가지고 있는 것이다. 그러면 이게 어떻게 가능한걸까? GenericViewSet
이 상속하고 있는 View
클래스를 보면 dispatch 함수가 있다.
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)
여기서 delete
요청이 오면 delete 함수를 찾아서 보내주고 있는 것이다. 그래서 def put, def patch 등을 이용해도 동일한 효과를 내주고 있는 것을 확인했다. getattr
의 의미만 알아도 조금 더 일찍 알 수 있지 않았을까 싶다.
댓글남기기