我尝试从另一个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})
我已经尝试了下面的代码行:
http_response = A.as_view()(request._request)
但提出以下例外:
从请求的数据流中阅读后无法访问正文
你知道该怎么做吗?
3条答案
按热度按时间2exbekwf1#
我认为在Django或DRF中调用另一个视图不是最好的做法。如果你想通过视图B从视图A访问业务逻辑,我建议你把业务逻辑放在一个外部函数中,这样你就可以在视图A和B上调用这个函数。
也就是说,你可以通过从DRF APIView调用HTTP方法 post,比如
A().post(request)
,由APIView B调用APIView A。6pp0gazn2#
您可以使用
requests
库向端点发送post
:A.views.py
B.views.py
Obs:在
B
上覆盖get
,以便您可以在可浏览API上看到消息。oo7oh9g93#
问题不在代码中,奇怪的是,我只需要重新运行Django服务器,代码就会按预期执行,所以
B.views.py
将是:更新
似乎
HttpRequest
AKArequest._request
在被Django Rest FrameworkView
解析器类读取后不能多次使用,这将导致调用read
方法,该方法将_request
对象的属性_read_started
更改为True
,之后,如果您尝试使用request.data
或request._request
将引发上面显示的异常,因为request.body
不再可访问,因为它依赖于_read_started
属性的值,更不用说HttpRequest
的值已经被转换为stream
对象并存储在内存中。解决方案
我发现了很多建议:
1-使用
Middleware
来存储request.body
,以便以后需要时使用。2-使用自定义解析器类,在将原始数据转换为
stream
对象之前,将其存储为request
对象中的属性。我发现这两个都有点复杂,所以我改变了从某个DRF
View
调用另一个APIView
的方式,如图所示: