我正在try 从另一个APIView呼叫APIView,代码类似于:

A.views.py


from rest_framework import views
from rest_framework.response import Response


class A(views.APIView):

   def post(self, request, *args, **kwargs):

       return Response({"message": "class A"})

B.views.py


from rest_framework import views
from rest_framework.response import Response

from A.views import A

class B(views.APIView):

   def post(self, request, *args, **kwargs):

       http_response = <call_A_APIView>

       return Response({"message": http_response})

我已经try 了下面的代码行:

http_response = A.as_view()(request._request)

但提出以下例外:

读取请求数据流后不能访问Body

你知道怎么做才是正确的吗?

推荐答案

问题不在代码中,奇怪的是,我只需要重新运行Django服务器,代码就会按预期执行,所以B.views.py将是:


from rest_framework import views
from rest_framework.response import Response

from A.views import A

class B(views.APIView):

   def post(self, request, *args, **kwargs):

       http_response = A.as_view()(request._request)

       return Response(http_response.data)

UPDATE

似乎HttpRequest AKA request._request在被Django REST FrameworkView解析器类读取后不能被多次使用,这将导致调用read方法,这将把_request对象的属性_read_started更改为True,之后如果您试图使用request.datarequest._request将引发上面所示的异常,因为request.body不再是可访问的,因为它依赖于_read_started属性的值,更不用说HttpRequest的值已经被转换成stream对象并存储在内存中.

SOLUTION

我发现了多个建议:

1-使用Middleware存储request.body,以备将来需要时使用.

2-使用自定义解析器类,在将原始数据转换为stream对象之前,将原始数据作为属性存储在request对象中.

我发现它们都有点复杂,所以我更改了从特定DRF View呼叫另一个APIView的方式,如下所示:


from rest_framework import views, status
from rest_framework.response import Response

from A.views import A
from C.views import C

class B(views.APIView):

   def post(self, request, *args, **kwargs):

       # Initialize a new instance of class view 'A'  
       a_view = A()

       # Calling HTTP 'POST' method with DRF request object.
       a_http_response = a_view.post(request)

       if a_http_response.status_code == status.status.HTTP_200_OK:

          # Initialize a new instance of class view 'C'  
          c_view = C()

          # Another calling HTTP 'POST' method with DRF request object.
          c_http_response = c_view.post(request)

          return(c_http_response.data)
       
       else:
          return Response(a_http_response.data)

Django相关问答推荐

未显示SWAGER上的一些示例架构

如何从列中捕获数据并将其添加到下拉菜单中,以便表单填充另一个表

如何使用来自另一个字段的信息创建字段

CsrfViewMiddleware 和 enforce_csrf 有什么区别?

Django 注释(),计数()

Django:获取每组最新的N条记录

在 Django Rest Framework 视图中,request.user 是在请求​​到达视图之前进行数据库调用还是数据库调用发生?

如何在 Django 模板中的计数器上进行 for 循环中断?

Django获取具有值的相关对象的计数并将其添加到注释中

如何在 Django 中将下一个 8 月 1 日添加为 DateTimeField 默认值

在 python 视图中检测移动浏览器

Django REST Framework如何在序列化程序中引发验证错误时指定错误代码

Django 1.9:字段与父模型中不存在的字段的字段冲突

django - 如何在验证之前处理/清理字段

重命名 django 元素的简单方法

Django 和 VirtualEnv 开发/部署最佳实践

django 管理列表中的外键显示

如何在 Django 1.9 中删除 DB (sqlite3) 以从头开始?

PyCharm 代码判断提示找不到模板文件,如何解决?

找不到 msguniq.确保您安装了 GNU gettext 工具 0.15 或更新版本. (Django 1.8 和 OSX ElCapitan)