可能在从u调用的APIView上有一个方法

2024-05-10 15:02:23 发布

您现在位置:Python中文网/ 问答频道 /正文

在Django Rest框架中,APIView类中的自定义方法的调用方式可能类似于.get().post()的调用方式。

我知道路由器使用@action()@link()装饰器是有可能的,我想知道你是否可以做一些类似于APIView的事情,但是拥有它,这样我就可以将方法设置为我想要的任何url。

我试过用@action()@api_view()来修饰类,但似乎没有任何效果。

我不确定应该在url中放入什么,以便端点真正调用类中的方法。我会使用CartAPIView.clear.as_view()CartAPIView.clear,还是CartAPIView.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'),
    ....
)

任何帮助都将不胜感激。


Tags: 方法pyviewapiurlgetas方式
3条回答

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

  • 因为基于类的视图显然是一个类,Django希望 未绑定函数(未附加到类或实例)作为视图,as_view通过创建未绑定函数来处理,并在该函数中实例化基于类的 查看。
  • as_view然后调用self.dispatch(request, *args, **kwargs),其中self是刚刚创建的实例化对象。
  • dispatch调用self.get(request, *args, **kwargs)self.post(request, *args, **kwargs),这取决于请求方法(或者putpatchdelete(如果允许并使用这些方法)。

对于像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'),
)

似乎您要找的是Function Based Views,在这里您可以用@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'),
    ....
)

@knbk和@almalki在这里发布的两个答案都是我所问问题的有效途径。然而,他们并没有显示出我在调查了几个小时后实际上做了什么。

我最终使用的视图集允许我将GETPOST等请求绑定到视图集类中的某个函数。通常你会使用路由器来自动绑定所有合适的函数,但我希望它们的绑定方式更灵活一些,所以我自己写出来。

# 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'),
    ....
)

相关问题 更多 >