How to Access method decorated with @action decorator of a view inherited from APIView Class in urls.py file in DRF?

I need to apply different permission on different methods of my View class which is inherited from APIView in a DRF application. To achieve this I am using @action decorator on my methods of view.

Here is views.py code

class UserView(APIView):

    @action(methods=['post'], detail=False, permission_classes=[AllowAny])
    def create(self, request):
        serializer = UserRegSerializer(data=request.data)
        user_service = UserService()
        try:
            serializer.is_valid(raise_exception=True)
            serialized_data = serializer.validated_data
            registered_user = user_service.create_user(serialized_data)
            payload = registered_user.__dict__
            response = ResponseGenerator(payload, constants.SUCCESS_KEY)
        except Exception as e:
            response = ResponseGenerator(e)
        return Response(data={"Response": response.get_custom_response()})

I am not getting that how could I access this method in my urls.py file against the pattern '/user', here is my urls.py code.

urlpatterns = [
    path('user', UserView.as_view()),
]

I was using ChatGPT to answer this query of mine. It suggested some ways to use a dictionary object passed {'post':'create'} in as_view() method of View in urls.py as following.

urlpatterns = [
    path('user', UserView.as_view({'post':'create'})),
]

In this it told me that key of the dictionary should be the http method used to access that method against the url pattern and value of dictionary should be the method which you want to access against the given url.

But its not working, and gives me following error when I try to start my project after writing this code in my urls.py

TypeError: APIView.as_view() takes 1 positional argument but 2 were given

I didn't find any solution to solve the problem that I am facing anywhere on Internet and in django's documentation as well.

I recommend you using Generic(Some Method)APIView. Because it can be changed to something good for your code scalability and reliability.

  1. Use CreateAPIView, you don't need to decorator for basic create function.
# views.py
class UserRegView(CreateAPIView):

    serializer_class = UserRegSerializer
    permission_classes = [AllowAny]
  1. If you need validation, write at the validate function. Your Response could be change sometime. Then, you should change you
# serializers.py
class UserRegSerializer(serializers.Serializer):
    somefield_1 = serializers.CharField()
    somefield_2 = serializers.CharField()
    newfield_1 = serializers.IntegerField(read_only=True)  # example

    def validate(self, attrs):

        a = attrs["somefield_1"]
        if a != "otherthing":
            raise ValidationError({"error": "Your error description some case"})
        return attrs

    def create(self, validated_data):
        instance = UserReg.objects.create(**validated_data)

        # Make Logic for instance or just validated_data or custom response whatever you want.
        # If you want to custom response, could write like this simple example.
        return {
            "somefield_1": "test1",
            "somefield_2": "test1",
            "newfield_1": "test1",
        }
  1. Now, you don't need any argument in as_view().
# urls.py
urlpatterns = [
    path("user_new", UserRegView.as_view()),
]
Back to Top