APIView 대 뷰셋

9577 단어 databaseviewsdjango
Django Rest Framework를 사용하여 Django에서 API를 빌드할 때 APIView 또는 ViewSets의 두 가지 컨트롤러 작성 옵션이 있습니다.

API보기


APIViewget , post , put , patchdelete HTTP 동사에 대한 메소드 핸들러를 제공합니다.
그러나 각 HTTP 동사에 대한 메서드를 작성해야 합니다. 예를 들어 Product 가 있는 ProductSerializer 리소스에 대한 보기를 작성하고 있습니다.

다음은 데이터베이스의 모든 제품을 반환하는 get() 메서드가 있는 보기의 예입니다.

from rest_framework.views import APIView


class ProductView(APIView):

    serializer_class = ProductSerializer

    def get(self, request, *args, **kwargs):

        products = Product.objects.all()

        serializer = self.serializer_class(products, many=True)

        return Response(serializer.data)

APIView 가능한 HTTP 요청이 실제로 많이 필요하지 않은 단순 엔드포인트에 가장 적합합니다. 나는 무엇을 의미합니까?
엔드포인트가 제품을 생성하기를 원한다고 가정합니다. 아주 간단합니다. 우리는 그것을 빨리 처리할 수 있습니다.

from rest_framework.views import APIView


class ProductView(APIView):

    serializer_class = ProductSerializer

    def get(self, request, *args, **kwargs):

        products = Product.objects.all()

        serializer = self.serializer_class(products, many=True)

        return Response(serializer.data)

    def post(self, request, *args, **kwargs):

        serializer = self.serializer_class(data=request.data)

        serializer.is_valid(raise_exception=True)

        return Response(serializer.data)


이제 제품을 생성할 수 있지만 제품을 사용할 수 없게 만드는 것과 같이 제품에 대해 특정 작업을 수행하려고 한다고 가정해 보겠습니다. 이렇게 하려면 POST 요청을 끝점으로 보내야 하며 나머지는 Product 모델의 일부 메서드를 사용하여 처리합니다.
ProductView 메서드가 이미 있기 때문에 post() 클래스에서는 그렇게 할 수 없습니다. 솔루션?
다른 항목을 추가하세요APIView ... 그리고 이것은 상당히 장황해지기 시작합니다.🤔
동일한 리소스에 대해 두 개의 서로 다른 URL 경로를 추가해야 한다는 점을 추가하지 마십시오. 이는 잘못된 API 설계일 수 있습니다.

솔루션? 💡ViewSets .

뷰셋



AViewSet는 논리를 하드 코딩하지 않고 모든 기본 HTTP 요청(GET, POST, PUT, DELETE)을 처리할 수 있는 클래스 기반 보기입니다.viewsets 모듈은 HTTP 요청 작업을 데이터베이스의 CRUD 작업에 매핑하는 ModelViewSet 클래스도 제공합니다.
예를 들어 ProductViewModelViewSet 를 다시 작성해 보겠습니다.

class ProductViewSet(ModelViewSet):

    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    http_method_names = ['get', 'post']


글쎄, 이것은 ProductView 와 같은 일을 하고 있습니다. 흥미롭지 않나요?🤩 이것은 동일한 리소스에 대해 특정 작업을 원할 때 더욱 흥미롭고 새 클래스를 추가할 필요가 없습니다.

class ProductViewSet(ModelViewSet):
...
    @action(detail=True, methods=['post'])
    def unavailable(self, request, *args, **kwargs):
        obj = self.get_object()

        obj.unavailable()

        return Response({'status': 'unavailable'})
...


그게 다가 아닙니다. viewsets로 작업하는 경우 URL 대신 라우터로 작업하게 됩니다.
라우터 파일에 viewsets를 등록하는 방법은 다음과 같습니다.

router = routers.DefaultRouter()

router.register(r'products', ProductViewSet)


이를 통해 products 끝점에 대해 다음과 같은 구조를 갖게 됩니다.


끝점
HTTP 방식
설명


/제품/
게시하다
새 제품 만들기

/제품/
가져 오기
모든 사용자 목록 가져오기

/제품/product_id/
가져 오기
제품 검색

/products/product_id/사용할 수 없음/
게시하다
제품을 사용할 수 없도록 설정


요약


APIViewViewSet 모두 올바른 사용 사례가 있습니다. 그러나 대부분의 경우 리소스에 대해서만 CRUD를 수행하는 경우 DRY 원칙을 준수하기 위해 ViewSets를 직접 사용할 수 있습니다.
그러나 더 복잡한 기능을 찾고 있다면 결국 viewsetsAPIView 의 하위 클래스이기 때문에 낮은 수준으로 갈 수 있습니다.

viewsetsviews에 대해 자세히 알아보세요.

bloggu.io을(를) 사용하여 게시된 기사. 무료로 사용해 보세요.

좋은 웹페이지 즐겨찾기