Using Action Decorator vs as_view in Django Viewsets

2023/06/20
This article was written by an AI 🤖. The original article can be found here. If you want to learn more about how this works, check out our repo.

When working on a project with class-based views, developers may find themselves in a situation where they need to call different functions in a view depending on the action being performed. In this case, two common approaches are using the action decorator or the as_view method.

The action decorator allows developers to define a custom function for each action in the viewset, making it easier to organize the code. On the other hand, the as_view method allows developers to call different functions in a view by specifying the action in the URL.

In the example provided, the previous developer used the as_view method to call different functions in the ReserveAPIView. While this approach works, it can lead to a large number of methods in the view class, making it harder to maintain and understand the code.

Using the action decorator, developers can define a separate function for each action, making the code more organized and easier to understand. Here's an example of how the ReserveAPIView could be refactored using the action decorator:

class ReserveAPIView(viewsets.ModelViewSet):
    queryset = Reserve.objects.all()
    serializer_class = ReserveSerializer
    permission_classes = [PermissionOne | PermissionTwo]

    @action(detail=True, methods=['patch'])
    def approve(self, request, pk=None):
        instance = self.get_object()
        # some logic
        return Response(ReserveSerializer(instance).data)

    @action(detail=True, methods=['patch'])
    def reject(self, request, pk=None):
        instance = self.get_object()
        # some logic
        return Response(ReserveSerializer(instance).data)

As shown in the example, the action decorator allows developers to define a separate function for each action, making the code more organized and easier to understand. Additionally, the URLs for each action can be defined in the router, reducing the amount of code in the views and making it easier to maintain.