Django rest framework non_atomic_requests based on HTTP method

Viewed 240

I am using Django Rest Framework and its class-based view, with database connection set to ATOMIC_REQUESTS=True.

To optimize the application, I would like to have it so that only PUT and POST requests are under transaction, but not GET. Since I have ATOMIC_REQUESTS on, the documentation says to use the decorator on the dispatch() method in the view. So this is what I tried:

class MyView(APIView):
    def get():
        print("I am in a transaction:", not transaction.get_autocommit())
        return Response({})

    def post():
        print("I am in a transaction:", not transaction.get_autocommit())
        return Response({})

    def put():
        print("I am in a transaction:", not transaction.get_autocommit())
        return Response({})

    def dispatch(self, request, *args, **kwargs):
        """Override dispatch method and selectively apply non_atomic_requests"""
        if request.method.lower() == "get":
            return self.non_atomic_dispatch(request, *args, **kwargs)
        else:
            return super().dispatch(request, *args, **kwargs)

    @transaction.non_atomic_requests
    def non_atomic_dispatch(self, request, *args, **kwargs):
        """Special dispatch method decorated with non_atomic_requests"""
        return super().dispatch(request, *args, **kwargs)

This does not work, since the get method still reports itself as under transaction, however, if I switch the decorator to look like this:

    ...
    
    @transaction.non_atomic_requests
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() == "get":
            return self.non_atomic_dispatch(request, *args, **kwargs)
        else:
            return super().dispatch(request, *args, **kwargs)

    def non_atomic_dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
        
    ...

This works, though obviously it's not what I want.

My questions are:

  1. Why does the placement of the decorator matter, if I am merely returning the same thing?

  2. How do I make this work the way I want?

0 Answers
Related