可以在从URL调用的APIView上有一个方法

JDW*_*dle 8 python api django django-rest-framework

在Django的REST框架是它有可能在一个自定义的方法APIView类调用方式类似,.get().post()将被调用.

我知道路由器使用@action()@link()装饰器是可能的,我试图弄清楚你是否可以做类似的东西APIView但是有它所以我可以将方法设置为我想要的任何网址.

我尝试过用这个课来装饰@action(),@api_view()但似乎没有任何效果.

我不确定我应该在url中放置一个端点来实际调用类中的方法.我会用CartAPIView.clear.as_view(),CartAPIView.clearCartAPIView.clear().我尝试了不同的调用组合,CartAPIView但没有任何效果.

这是我正在尝试做的一个例子:

# views.py
class CartAPIView(APIView):
    @api_view(['POST'])
    def clear(self, request):
        """Clear the users cart."""
        queryset = Cart.objects.get(user=request.user)

        queryset.clear_cart()

        serializer = CartSerializer(queryset)

        return Response(serializer.data, status=status.HTTP_200_OK)

# urls.py
urlpatterns = patterns('app.views',
    ....
    url(r'^cart/clear/$', CartAPIView.clear.as_view(), name='clear_cart_api'),
    ....
)
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

knb*_*nbk 10

您似乎忽略了基于类的视图流的工作原理.

  • 由于基于类的视图是一个类(显然),并且Django期望未绑定的函数(不附加到类或实例)作为视图,as_view通过创建未绑定的函数来处理它,并在该函数中实例化基于类的视图.
  • as_view然后调用self.dispatch(request, *args, **kwargs),self刚刚创建的实例化对象在哪里.
  • dispatch调用任一self.get(request, *args, **kwargs)self.post(request, *args, **kwargs),根据请求方法(或put,patch或者delete如果这些被允许和使用).

clear除非您覆盖其中一种方法来调用,否则没有像您的函数那样的自定义函数的空间self.clear(request).相当于@api_view(['POST'])覆盖post(request, *args, **kwargs)方法:

# views.py
class CartAPIView(APIView):
    def post(self, request, *args, **kwargs):
        # Why would you call this 'queryset'? It's a single object.
        cart = Cart.objects.get(user=request.user)
        cart.clear_cart()

        serializer = CartSerializer(cart)
        return Response(serializer.data, status=status.HTTP_200_OK)

# urls.py
urlpatterns = patterns('app.views',
    url(r'^cart/clear/$', CartAPIView.as_view(), name='clear_cart_api'),
)
Run Code Online (Sandbox Code Playgroud)


alm*_*lki 5

似乎您正在寻找的是基于函数的视图,您可以在其中装饰函数@api_view()

from rest_framework.decorators import api_view

@api_view(['POST'])
def clear(request):
    """Clear the users cart."""
    queryset = Cart.objects.get(user=request.user)

    queryset.clear_cart()

    serializer = CartSerializer(queryset)

    return Response(serializer.data, status=status.HTTP_200_OK)


# urls.py
urlpatterns = patterns('app.views',
    ....
    url(r'^cart/clear/$', 'clear', name='clear_cart_api'),
    ....
)
Run Code Online (Sandbox Code Playgroud)


JDW*_*dle 5

@knbk 和 @almalki 在这里发布的两个答案都是我所问问题的有效方法。然而,他们并没有显示我在研究几个小时左右后实际上最终做了什么。

我最终使用了 ViewSets,它允许我将GETPOST等请求绑定到 ViewSet 类中的某个函数。通常,您会使用路由器自动绑定所有适当的函数,但我希望它们的绑定方式更加灵活,所以我自己将它们写出来。

# views.py
class CartViewSet(ViewSet):
    def clear(self, request):
        """Clear the users cart."""
        queryset = Cart.objects.get(user=request.user)

        queryset.clear_cart()

        serializer = CartSerializer(queryset)

        return Response(serializer.data, status=status.HTTP_200_OK)

clear_cart_viewset = CartViewSet.as_view({
    'post': 'clear'
})

# urls.py
urlpatterns = patterns('app.views',
    ....
    url(r'^cart/clear/$', 'clear_cart_viewset', name='clear_cart_api'),
    ....
)
Run Code Online (Sandbox Code Playgroud)