2017-08-24 69 views
2

我們有一個APIViewFooView),可以直接通過URL來訪問。嵌套APIView中斷請求。如果request.FILES屬性被稱爲

我們還有另外一個APIViewAPIKeyImportView,它將根據文件名重複使用FooView(這樣做是爲了與API兼容)。

但是,當從APIKeyImportView訪問request.FILES查看文件名時,request.FILESFooView中變爲空。

似乎訪問request.FILES意願使得它未通過可用嵌套視圖。

有沒有辦法解決這個問題?

class FooView(APIView): 
     permission_classes = (permissions.IsAuthenticated,) 

     def post(self, request, vendor): 
      file = request.FILES.get('file') 
      if not file: 
       return Response(status=status.HTTP_400_BAD_REQUEST) 
      return Response() 


    class APIKeyImportView(APIView): 
     permission_classes = (permissions.IsAuthenticated,) 
     authentication_classes = (ApiKeyAuthentication,) 

     def post(self, request): 
      file = request.FILES.get('file') 
      if not file: 
       return Response(status=status.HTTP_400_BAD_REQUEST) 
      name = file.name 

      if name.startswith('FOO'): 
       return FooView.as_view()(request=request) 
      else: 
       return Response(status=status.HTTP_400_BAD_REQUEST) 

APIKeyImportView拆卸request.Files驗證將使其在FooView訪問,但它種錯過的點。

在PyCharm中檢查request也會使其在FooView中無法使用,因爲調試器會調用屬性。

class APIKeyImportView(APIView): 
     permission_classes = (permissions.IsAuthenticated,) 
     authentication_classes = (ApiKeyAuthentication,) 

     def post(self, request): 
      return FooView.as_view()(request=request) 

這些解決方案都無法正常工作:

django modifying the request object

測試過的版本:

  • 的Django 1.9.5
  • Django的休息框架3.3.3
  • 的Python 3.4.2

回答

2

我找到了一個解決方法是通過request.FILES,但我不知道它是否有副作用

class FooView(APIView): 
     permission_classes = (permissions.IsAuthenticated,) 

     _files = None 

     @property 
     def request_files(self): 
      if self._files: 
       return self._files 
      return self.request.FILES 

     def post(self, request, vendor): 
      file = self.request_files.get('file') 
      if not file: 
       return Response(status=status.HTTP_400_BAD_REQUEST) 
      return Response() 


    class APIKeyImportView(APIView): 
     permission_classes = (permissions.IsAuthenticated,) 
     authentication_classes = (ApiKeyAuthentication,) 

     def post(self, request): 
      file = request.FILES.get('file') 
      if not file: 
       return Response(status=status.HTTP_400_BAD_REQUEST) 
      name = file.name 

      if name.startswith('FOO'): 
       # Passing FILES here 
       return FooView.as_view(_files=request.FILES)(request=request) 
      else: 
       return Response(status=status.HTTP_400_BAD_REQUEST)