I need similar @action
detail routes on multiple ViewSets. I want to make sure they remain consistent. I don't want to put @action(methods=["post"], detail=True, url_path="something")
in 20 places when I already know these parameters and the method handling the request will be the same everywhere.
My first attempt to solve htis was to put the method and its decorator in a base class and have my ViewSets inherit from it, but because decoration of methods is not inherited, DRF does not recognise my @action
s as such in the inheriting classes. The methods get inherited but not the decorator.
So, to solve that, I could put @action
everywhere but that would mean a duplication of its arguments in many places. I don't want that.
To avoid duplication, I am trying to specialise @action
by using partial application. This will give me a custom @action
decorator with the arguments which will be the same everywhere fixed in place.
This leaves me with something like this (example code):
specialised_action = partial(action, methods=["post"], detail=True, url_path="my-action-url")
class SomeViewSet(GenericViewSet):
@specialised_action
def action_handler(self, request, *args, **kwargs):
print("do something")
But it doesn't work, I get this error:
TypeError: action() got multiple values for argument 'methods'
My questions:
methods
passed multiple times?@action
s across many ViewSets?The problem was that @action
isn't a decorator, it returns a decorator. So there is no need to use partial()
.
Instead of:
specialised_action = partial(action, methods=["post"], detail=True, url_path="my-action-url")
Simply do:
specialised_action = action(methods=["post"], detail=True, url_path="my-action-url")
And I got my specialised version of @action
with fixed arguments.