[Fixed]-Check view method parameter name in Django class based views

1👍

What I want seemed impossible in the current state of the libraries. So here’s what I finally went with.

            parameter_names = inspect.getargspec(decorated_function).args

            if "phone_number" in parameter_names or "phone_number" in injectables:
                kwargs["phone_number"] = decoded_payload["phone"]
            if "user_id" in parameter_names:
                kwargs["user_id"] = decoded_payload["user_id"]
            if "email" in parameter_names:
                kwargs["email"] = decoded_payload["email"]

            request.__setattr__("JWT", {})
            request.JWT["phone_number"] = decoded_payload["phone"]
            request.JWT["user_id"] = decoded_payload["user_id"]
            request.JWT["email"] = decoded_payload["email"]

This decorator will automatically populate parameters in method based views as intended.

But it will also inject an JWT attribute to the request object for the class based views to use. Like request.GET and request.POST.

5👍

I found this post: Function decorators with parameters on a class based view in Django

which may provide the answer to your problem:

If you want to pass a decorator with parameters, you only need to:

  • Evaluate the parameters in the decorator-creator function.

  • Pass the evaluated value to @method_decorator.

The above mentioned and the code provided in the linked answer taken under consideration, you should:

injectables=[inject_1, inject_2, ..., inject_n]
decorators = [csrf_exempt, need_jwt_verification(injectables)]

@method_decorator(decorators, name="dispatch")
class EMController(View):
    ...

Leaving my previous mistaken answer here for legacy reasons, don’t try this at home (or anywhere, in django, for that matter!!)

If we observe the “decorating a class” docs, we can see the following:

Or, more succinctly, you can decorate the class instead and pass the name of the method to be decorated as the keyword argument name:

so you have to change the name argument of your @method_decorator to match the method that will apply to:

decorators = [csrf_exempt, need_jwt_verification(injectables=[])]

@method_decorator(decorators, name='get')
@method_decorator(decorators, name='post')
class EMController(View):

Personally I prefer to place my decorators on top of the specific method they will apply to:

class EMController(View):
    @method_decorator(decorators)
    def get(self, request, phone_number, event_id):
        ...

    @method_decorator(decorators)    
    def post(self, request, phone_number, event_id):
        ...

Leave a comment