django - 如果调用 request.FILES 属性,则嵌套 APIView 会中断请求

标签 django debugging request django-rest-framework

我们有一个可以通过 URL 直接访问的 APIView (FooView)。

我们有另一个 APIView APIKeyImportView 将根据文件名重用 FooView(这样做是为了与 API 兼容)。

但是,当从 APIKeyImportView 访问 request.FILES 以查看文件名时,request.FILESFooView 中变为空

访问 request.FILES 似乎会使嵌套 View 无法使用它。

有解决办法吗?

  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-rest-framework 3.3.3
  • python 3.4.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)

关于django - 如果调用 request.FILES 属性,则嵌套 APIView 会中断请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45864002/

相关文章:

python - 如何呈现响应?

python - 如何在基于类的通用 View 中设置 cookie

visual-studio-2010 - 调试汇编代码(Intel 8086)

c++ - WPD API 检测设备是否是电话?

ios - 如何确保我一次只有 1 个异步 NSURLConnection?

html - 使用 grequests 从异步请求中提取文本

Azure 上的 Django 不加载静态文件

python - Django 使用 GET 过滤搜索结果

ios - XCode 7调试区工具栏区别

node.js - 无法在 setTimeout 中将流发送到服务器