I’ve been using the Django rest framework, and I’m trying to customize the get_parsers method in my UserViewset, I looked at the docs and found a similar use case with permission classes in docs, and I tried to customize the get_parsers like this
class UserViewset(viewsets.ModelViewSet): serializer_class = UserSerializer # Redefine get_parsers, so that only the update methods have form-data media type def get_parsers(self): if self.action == 'update' or self.action == 'partial_update': parser_classes = [FormParser, MultiPartParser] else: parser_classes = [JSONParser] return [parser() for parser in parser_classes]
but I keep getting the error:
AttributeError at /api/auth/users/: 'UserViewset' object has no attribute 'action'
I tried the use case found in the docs and it worked perfectly.
What am I doing wrong here ?
So, thanks to fb.com/laidani.basset @bdbd and @willem-van-onsem and u/vikingvynotking, I’ve been able to fix it with 2 different solutions:
The first is to override initialize_request like this, the idea is to set the request parsers to the instance of which parser you want; the drop back is when you’re using swagger or any API doc, it’ll not differentiate between the method parsers and it’ll be just one parser, in my case it’s JSONParser:
def initialize_request(self, request, *args, **kwargs): request = super().initialize_request(request, *args, **kwargs) print(request.method) if request.method in ['PUT', 'PATCH']: request.parsers = [FormParser(), MultiPartParser()] else: request.parsers = [JSONParser()] self.action = self.action_map.get(request.method.lower()) return request
The second solution is to override initialize_request so that the self.action is called before calling the request, and then use the get_parsers method as you like, in this case, the swagger will differentiate between the parsers of each method:
def initialize_request(self, request, *args, **kwargs): self.action = self.action_map.get(request.method.lower()) return super().initialize_request(request, *args, **kwargs)
Answered By – Sohaib Smahi