Django REST Framework에서 제공하는 세 가지 방식의 API 뷰 작성 방법이 있다.
@api_view
데코레이터- APIView 클래스
- viewsets.ModelViewSet 클래스
각 방식에 따라 뷰를 작성하는 방법과 router 연결 방법이 다름으로 주의해야한다.
@api_view 데코레이터
기존의 Django 뷰와 유사한 함수 기반 뷰를 작성하는 방식입니다. 이 데코레이터를 사용하여 각 HTTP 메소드에 대한 적절한 응답을 반환할 수 있습니다. 이 방식은 간단한 API를 작성할 때 유용하다.
#views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(["GET"])
def api_view_test(request):
content = {"message": "Hello, Django!"}
return Response(content)
@api_view
데코레이터는 HTTP 요청 방법(GET, POST, PUT, DELETE 등)에 따라 뷰 함수를 호출 해준다. 만약 @api_view
데코레이터가 없는 경우에는 DRF가 해당 함수를 API 뷰로 인식하지 않기 때문에, URL에 매핑되지 않는다.
배열 내부에 요청 방법에 따라 처리를 달리하고 싶다면, @api_view
를 통해 원하는 메서드를 명시해주면 된다.
@api_view(["GET", "POST"])
물론 배열이기 때문에 한가지 이상을 명시해도 가능하다.
여러가지를 명시하는 경우, request.method를 통해 분리하여 처리해주면 된다.
#views.py
@api_view(["GET", "POST"])
def api_view_test(request):
if request.method == "GET":
return Response()
if request.method == "POST":
return Rsponse()
#urls.py
from django.urls import include, path
from product.views import (
api_view_test,
)
urlpatterns = [
# <http://127.0.0.1:8000/api/api-view-test/>
path("api-view-test/", api_view_test, name="api-view-test"),
]
APIView 클래스
Django의 View 클래스를 상속받아서 클래스 기반 뷰를 작성하는 방식입니다. get()
, post()
, put()
, delete()
등의 메소드를 오버라이드하여 각 HTTP 메소드에 대한 적절한 응답을 반환할 수 있습니다. 이 방식은 좀 더 복잡한 로직이 필요한 API를 작성할 때 유용하다.
#views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class APIViewTest(APIView):
def get(self, request):
content = {"message": "Hello, Django!"}
return Response(content)
요청 메서드에 대응하는 메서드 이름이 정해져 있습니다. 따라서 메서드 이름을 다른 이름으로 변경하면 해당 메서드가 호출되지 않는다.
만약 다른 이름으로 메서드를 정의하려면 APIView
를 상속받지 않고 django.views.View
를 상속받아 직접 뷰를 구현하는 방법도 있습니다. 이 경우에는 메서드 이름을 원하는대로 지정할 수 있다.
#views.py
from django.views import View
from django.http import JsonResponse
class MyView(View):
def my_get_method(self, request, *args, **kwargs):
# GET 요청에 대한 처리
return JsonResponse({'message': 'This is a GET request'})
def my_post_method(self, request, *args, **kwargs):
# POST 요청에 대한 처리
return JsonResponse({'message': 'This is a POST request'})
def my_put_method(self, request, *args, **kwargs):
# PUT 요청에 대한 처리
return JsonResponse({'message': 'This is a PUT request'})
def my_delete_method(self, request, *args, **kwargs):
# DELETE 요청에 대한 처리
return JsonResponse({'message': 'This is a DELETE request'})
이렇게 사용하면 반드시 오류가 발생한다. 각각의 요청 메서드에 대한 구분을 자동으로 처리하지 않기 때문에 아래와 같이 개발자가 직접 구분해 주어야 한다.
#views.py
from django.views import View
from django.http import JsonResponse
class MyView(View):
def dispatch(self, request, *args, **kwargs):
if request.method == 'GET':
return self.get_method(request, *args, **kwargs)
elif request.method == 'POST':
return self.post_method(request, *args, **kwargs)
elif request.method == 'PUT':
return self.put_method(request, *args, **kwargs)
elif request.method == 'DELETE':
return self.delete_method(request, *args, **kwargs)
else:
return JsonResponse({'error': 'Unsupported HTTP method'})
def get_method(self, request, *args, **kwargs):
# GET 요청에 대한 처리
return JsonResponse({'message': 'This is a GET request'})
def post_method(self, request, *args, **kwargs):
# POST 요청에 대한 처리
return JsonResponse({'message': 'This is a POST request'})
def put_method(self, request, *args, **kwargs):
# PUT 요청에 대한 처리
return JsonResponse({'message': 'This is a PUT request'})
def delete_method(self, request, *args, **kwargs):
# DELETE 요청에 대한 처리
return JsonResponse({'message': 'This is a DELETE request'})
위 코드에서는 dispatch()
메서드를 오버라이딩하여 각각의 요청 메서드에 대한 구분을 수행하고, 구분된 요청 메서드에 대응하는 메서드를 호출하도록 구현한다.
이렇게 하면 django.views.View
를 상속받아 각각의 HTTP 요청 메서드에 대응하는 메서드가 다른 이름을 갖더라도, 요청 메서드에 대한 구분을 dispatch()
함수가 알아서 매핑하여 처리 해준다.
때문에 URL을 연결할 때 아래와 같이 간략하게 사용할 수 있다.
#urls.py
from django.urls import path
from product.views import (
APIViewTest,
)
urlpatterns = [
# <http://127.0.0.1:8000/api/apiview-test/>
path("apiview-test/", APIViewTest.as_view(), name="apiview-test"),
]
viewsets.ModelViewSet 클래스
APIView
클래스를 상속받아서 모델 기반 뷰를 작성하는 방식입니다. 이 클래스를 사용하면 일반적으로 자주 사용하는 CRUD 작업을 처리할 수 있습니다. 이 방식은 RESTful API를 작성할 때 유용하다.
모델 기반으로 작동하기 때문에 사용하기에 앞서 models.py
를 통한 모델 생성이 꼭 선행되어야 한다.
#views.py
from .models import Test
from rest_framework import viewsets
class ViewSetTest(viewsets.ModelViewSet):
queryset = Test.objects.all()
serializer_class = PostSerializer
def list(self, request, *args, **kwargs):
content = {"message": "Hello, Django!"}
return Response(content)
list() 메소드를 통해 모든 객체의 목록을 반환하며, 이를 오버라이드하여 원하는 응답을 반환할 수 있다.
기본적인 메소드들은 list, create, update, destroy 등이 있고, 이 외에 다른 메소드들이 있는데 공식 문서에서 확인할 수 있다..
- list(self, request, args, kwargs) - 모든 객체의 목록을 반환합니다.
- create(self, request, args, kwargs) - 새로운 객체를 생성합니다.
- update(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체를 업데이트합니다.
- destroy(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체를 삭제합니다.
- retrieve(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 단일 객체를 반환합니다.
- partial_update(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체의 일부를 업데이트합니다.
#urls.py
from django.urls import include, path
from rest_framework import routers
from product.views import ( ViewSetTest )
router = routers.DefaultRouter()
router.register(r"view-set", ViewSetTest)
urlpatterns = [
path("", include(router.urls)),
]
해당 방법의 동작 순서는 아래와 같아.
- router = routers.DefaultRouter() 해당 라인을 통해 모듈을 사용하여 라우터를 생성한다.
- router.register() 메소드를 사용하여 클래스를 라우터에 등록한다.
- router.urls를 path() 함수의 두 번째 인자로 전달하여 URL을 연결한다.
해당 방법은 위의 다른 방법들과는 달리 자동으로 생성되기 때문에 프로젝트의 urls.py를
#urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include("product.urls")),
path("api_auth/", include("rest_framework.urls", namespace="rest_framework")),
]
이와 같이 작성하면 router로 자동 생성된 것 들을 한눈에 볼 수 있게 해준다.

때문에 DB를 사용해야 하는 API의 경우 해당 방법을 통해 생성하는게 편리하다.
'🛠️Framework > 🚀Django' 카테고리의 다른 글
Django CORS 설정 오류 해결 (0) | 2023.04.07 |
---|
Django REST Framework에서 제공하는 세 가지 방식의 API 뷰 작성 방법이 있다.
@api_view
데코레이터- APIView 클래스
- viewsets.ModelViewSet 클래스
각 방식에 따라 뷰를 작성하는 방법과 router 연결 방법이 다름으로 주의해야한다.
@api_view 데코레이터
기존의 Django 뷰와 유사한 함수 기반 뷰를 작성하는 방식입니다. 이 데코레이터를 사용하여 각 HTTP 메소드에 대한 적절한 응답을 반환할 수 있습니다. 이 방식은 간단한 API를 작성할 때 유용하다.
#views.py from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(["GET"]) def api_view_test(request): content = {"message": "Hello, Django!"} return Response(content)
@api_view
데코레이터는 HTTP 요청 방법(GET, POST, PUT, DELETE 등)에 따라 뷰 함수를 호출 해준다. 만약 @api_view
데코레이터가 없는 경우에는 DRF가 해당 함수를 API 뷰로 인식하지 않기 때문에, URL에 매핑되지 않는다.
배열 내부에 요청 방법에 따라 처리를 달리하고 싶다면, @api_view
를 통해 원하는 메서드를 명시해주면 된다.
@api_view(["GET", "POST"])
물론 배열이기 때문에 한가지 이상을 명시해도 가능하다.
여러가지를 명시하는 경우, request.method를 통해 분리하여 처리해주면 된다.
#views.py @api_view(["GET", "POST"]) def api_view_test(request): if request.method == "GET": return Response() if request.method == "POST": return Rsponse()
#urls.py from django.urls import include, path from product.views import ( api_view_test, ) urlpatterns = [ # <http://127.0.0.1:8000/api/api-view-test/> path("api-view-test/", api_view_test, name="api-view-test"), ]
APIView 클래스
Django의 View 클래스를 상속받아서 클래스 기반 뷰를 작성하는 방식입니다. get()
, post()
, put()
, delete()
등의 메소드를 오버라이드하여 각 HTTP 메소드에 대한 적절한 응답을 반환할 수 있습니다. 이 방식은 좀 더 복잡한 로직이 필요한 API를 작성할 때 유용하다.
#views.py from rest_framework.views import APIView from rest_framework.response import Response class APIViewTest(APIView): def get(self, request): content = {"message": "Hello, Django!"} return Response(content)
요청 메서드에 대응하는 메서드 이름이 정해져 있습니다. 따라서 메서드 이름을 다른 이름으로 변경하면 해당 메서드가 호출되지 않는다.
만약 다른 이름으로 메서드를 정의하려면 APIView
를 상속받지 않고 django.views.View
를 상속받아 직접 뷰를 구현하는 방법도 있습니다. 이 경우에는 메서드 이름을 원하는대로 지정할 수 있다.
#views.py from django.views import View from django.http import JsonResponse class MyView(View): def my_get_method(self, request, *args, **kwargs): # GET 요청에 대한 처리 return JsonResponse({'message': 'This is a GET request'}) def my_post_method(self, request, *args, **kwargs): # POST 요청에 대한 처리 return JsonResponse({'message': 'This is a POST request'}) def my_put_method(self, request, *args, **kwargs): # PUT 요청에 대한 처리 return JsonResponse({'message': 'This is a PUT request'}) def my_delete_method(self, request, *args, **kwargs): # DELETE 요청에 대한 처리 return JsonResponse({'message': 'This is a DELETE request'})
이렇게 사용하면 반드시 오류가 발생한다. 각각의 요청 메서드에 대한 구분을 자동으로 처리하지 않기 때문에 아래와 같이 개발자가 직접 구분해 주어야 한다.
#views.py from django.views import View from django.http import JsonResponse class MyView(View): def dispatch(self, request, *args, **kwargs): if request.method == 'GET': return self.get_method(request, *args, **kwargs) elif request.method == 'POST': return self.post_method(request, *args, **kwargs) elif request.method == 'PUT': return self.put_method(request, *args, **kwargs) elif request.method == 'DELETE': return self.delete_method(request, *args, **kwargs) else: return JsonResponse({'error': 'Unsupported HTTP method'}) def get_method(self, request, *args, **kwargs): # GET 요청에 대한 처리 return JsonResponse({'message': 'This is a GET request'}) def post_method(self, request, *args, **kwargs): # POST 요청에 대한 처리 return JsonResponse({'message': 'This is a POST request'}) def put_method(self, request, *args, **kwargs): # PUT 요청에 대한 처리 return JsonResponse({'message': 'This is a PUT request'}) def delete_method(self, request, *args, **kwargs): # DELETE 요청에 대한 처리 return JsonResponse({'message': 'This is a DELETE request'})
위 코드에서는 dispatch()
메서드를 오버라이딩하여 각각의 요청 메서드에 대한 구분을 수행하고, 구분된 요청 메서드에 대응하는 메서드를 호출하도록 구현한다.
이렇게 하면 django.views.View
를 상속받아 각각의 HTTP 요청 메서드에 대응하는 메서드가 다른 이름을 갖더라도, 요청 메서드에 대한 구분을 dispatch()
함수가 알아서 매핑하여 처리 해준다.
때문에 URL을 연결할 때 아래와 같이 간략하게 사용할 수 있다.
#urls.py from django.urls import path from product.views import ( APIViewTest, ) urlpatterns = [ # <http://127.0.0.1:8000/api/apiview-test/> path("apiview-test/", APIViewTest.as_view(), name="apiview-test"), ]
viewsets.ModelViewSet 클래스
APIView
클래스를 상속받아서 모델 기반 뷰를 작성하는 방식입니다. 이 클래스를 사용하면 일반적으로 자주 사용하는 CRUD 작업을 처리할 수 있습니다. 이 방식은 RESTful API를 작성할 때 유용하다.
모델 기반으로 작동하기 때문에 사용하기에 앞서 models.py
를 통한 모델 생성이 꼭 선행되어야 한다.
#views.py from .models import Test from rest_framework import viewsets class ViewSetTest(viewsets.ModelViewSet): queryset = Test.objects.all() serializer_class = PostSerializer def list(self, request, *args, **kwargs): content = {"message": "Hello, Django!"} return Response(content)
list() 메소드를 통해 모든 객체의 목록을 반환하며, 이를 오버라이드하여 원하는 응답을 반환할 수 있다.
기본적인 메소드들은 list, create, update, destroy 등이 있고, 이 외에 다른 메소드들이 있는데 공식 문서에서 확인할 수 있다..
- list(self, request, args, kwargs) - 모든 객체의 목록을 반환합니다.
- create(self, request, args, kwargs) - 새로운 객체를 생성합니다.
- update(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체를 업데이트합니다.
- destroy(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체를 삭제합니다.
- retrieve(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 단일 객체를 반환합니다.
- partial_update(self, request, pk, args, kwargs) - 주어진 고유 식별자에 해당하는 객체의 일부를 업데이트합니다.
#urls.py from django.urls import include, path from rest_framework import routers from product.views import ( ViewSetTest ) router = routers.DefaultRouter() router.register(r"view-set", ViewSetTest) urlpatterns = [ path("", include(router.urls)), ]
해당 방법의 동작 순서는 아래와 같아.
- router = routers.DefaultRouter() 해당 라인을 통해 모듈을 사용하여 라우터를 생성한다.
- router.register() 메소드를 사용하여 클래스를 라우터에 등록한다.
- router.urls를 path() 함수의 두 번째 인자로 전달하여 URL을 연결한다.
해당 방법은 위의 다른 방법들과는 달리 자동으로 생성되기 때문에 프로젝트의 urls.py를
#urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), path("api/", include("product.urls")), path("api_auth/", include("rest_framework.urls", namespace="rest_framework")), ]
이와 같이 작성하면 router로 자동 생성된 것 들을 한눈에 볼 수 있게 해준다.

때문에 DB를 사용해야 하는 API의 경우 해당 방법을 통해 생성하는게 편리하다.
'🛠️Framework > 🚀Django' 카테고리의 다른 글
Django CORS 설정 오류 해결 (0) | 2023.04.07 |
---|