In Django Rest Framework is it possible to have a custom method in an APIView class be called similar to how .get() or .post() would be called.
I know it's possible with routers using the @action() or @link() decorators, I'm trying to figure out if you can do something similar to an APIView but have it so I can set the method to whatever url I want.
I've tried decorating the class with @action() and @api_view() but nothing seems to have worked.
I'm not exactly sure what I should put in the url for an endpoint to actually call the method in the class. Would I use CartAPIView.clear.as_view(), CartAPIView.clear, or CartAPIView.clear(). I've tried different combinations of calls to CartAPIView but nothing has worked.
Here's an example of what I'm trying to do:
# 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'),
    ....
)
Any help would be appreciated.
You seem to miss the point of how a class-based view's flow works.
as_view handles that by creating an unbound function, and in that function instantiating the class-based
view.  as_view then calls self.dispatch(request, *args, **kwargs), where self is the instantiated object that's just created.dispatch calls either self.get(request, *args, **kwargs) or self.post(request, *args, **kwargs), depending on the request method (or put, patch or delete if those are allowed and used). There's no room for a custom function like your clear function, unless you override one of these methods to call self.clear(request). The equivalent of @api_view(['POST']) would be to override the post(request, *args, **kwargs) method:
# 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'),
)
                        It seems what you are looking for is Function Based Views, where you can decorate a function with @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'),
    ....
)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With