首页 > 解决方案 > AttributeError 'UserViewset' 对象没有属性 'action'

问题描述

我一直在使用 Django rest 框架,我正在尝试在我的 UserViewset 中自定义 get_parsers 方法,我查看了文档并在 docs 中找到了一个与权限类类似的用例我尝试像这样自定义 get_parsers

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]

但我不断收到错误消息:AttributeError at /api/auth/users/: 'UserViewset' object has no attribute 'action' 我尝试了文档中的用例,它运行良好。我在这里做错了什么?

标签: pythondjangodjango-rest-framework

解决方案


因此,感谢 fb.com/laidani.basset @bdbd 和 @willem-van-onsem 以及 u/vikingvynotking,我已经能够使用 2 种不同的解决方案来修复它:

  • 第一个是像这样覆盖initialize_request,想法是将请求解析器设置为您想要的解析器的实例;回退是当您使用 swagger 或任何 API 文档时,它不会区分方法解析器,它只是一个解析器,在我的情况下它是 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
    
  • 第二种解决方案是重写initialize_request,让self.action在调用请求之前被调用,然后随心所欲地使用get_parsers方法,在这种情况下,swagger会区分每个方法的解析器:

     def initialize_request(self, request, *args, **kwargs):
         self.action = self.action_map.get(request.method.lower())
         return super().initialize_request(request, *args, **kwargs)
    

推荐阅读