You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework中request调用APIView报错,求解决方法

DRF内部API调用与外部请求报错修复方案

问题场景

编写了如下DRF代码,其中POST方法的MrgCompInsert类需要先调用内部的MrgCompInfo(含GET方法的APIView)获取数据,再将数据POST到外部RESTful API:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework import status

class MrgCompInsert(APIView):
    def post(self, request):
        try:
            # Use rest_framework.request.Request to make the initial request
            merge_company_info_view = MrgCompInfo.as_view()(Request(request))
            organization_data_response = merge_company_info_view.data

            if organization_data_response.status_code == status.HTTP_200_OK:
                # Access the data attribute from the Response object
                organization_data_post = organization_data_response.data

                post_url = 'https://example.com/'
                # Use rest_framework.request.Request to make the subsequent request
                merge_to_kloo_post = Request(request).client.post(post_url, organization_data_post, format='json')

                if merge_to_kloo_post.status_code == status.HTTP_200_OK:
                    return Response({'message': 'Data sent successfully to the second API'}, status=status.HTTP_200_OK)
                else:
                    return Response({'error': 'Failed to send data to the second API'},
                                    status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                return Response({'error': 'Failed to retrieve Category list'},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

单独运行MrgCompInfo正常,但MrgCompInsert运行时抛出500错误:

HTTP 500 Internal Server Error
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "error": "The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`."
}

尝试导入django.http.HttpRequest修改后仍报相同错误:

from django.http import HttpRequest

organization_data_response = MrgCompInfo(HttpRequest)
merge_to_post = HttpRequest().POST(post_url, organization_data_post, format='json'), 

错误原因

  1. 内部API调用错误:APIView的as_view()返回的视图函数需要接收原生Django HttpRequest实例,但你传入了DRF封装后的rest_framework.request.Request,且直接实例化APIView类的方式也不正确。
  2. 外部请求方式错误:HttpRequest是Django处理请求的类,不能用来主动发送外部POST请求;DRF的client主要用于测试场景,不适合业务代码中调用外部API。
  3. Response处理逻辑错误:错误地将response.data当作Response对象来访问status_code,实际response.data只是响应体的字典数据。

修复方案

关键修改点

  • 调用内部APIView时,从DRF的Request中取出原生HttpRequest,或构造符合GET请求的原生HttpRequest实例,并传递必要的请求属性。
  • 使用requests库发送外部POST请求(需先安装:pip install requests),这是业务代码中调用外部API的标准方式。
  • 修正Response对象的处理逻辑,正确获取状态码和响应数据。

修复后完整代码

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import requests
from django.http import HttpRequest

class MrgCompInsert(APIView):
    def post(self, request):
        try:
            # 构造内部GET请求的原生HttpRequest
            internal_request = HttpRequest()
            internal_request.method = 'GET'
            # 复制原请求的必要属性(如headers、用户身份等)
            internal_request.headers = request.headers
            internal_request.user = request.user
            # 若MrgCompInfo有特定路由需求,可调整path属性

            # 调用内部APIView的视图函数
            merge_company_response = MrgCompInfo.as_view()(internal_request)

            if merge_company_response.status_code == status.HTTP_200_OK:
                organization_data = merge_company_response.data

                post_url = 'https://example.com/'
                # 使用requests发送外部POST请求
                external_response = requests.post(
                    post_url,
                    json=organization_data,
                    headers={'Content-Type': 'application/json'},
                    timeout=10  # 添加超时防止请求挂起
                )

                if external_response.status_code == status.HTTP_200_OK:
                    return Response(
                        {'message': 'Data sent successfully to the second API'},
                        status=status.HTTP_200_OK
                    )
                else:
                    return Response(
                        {'error': 'Failed to send data to the second API'},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR
                    )
            else:
                return Response(
                    {'error': 'Failed to retrieve Category list'},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

额外优化建议

  • 如果MrgCompInfo的核心逻辑只是获取数据,建议直接调用其对应的业务函数,而非通过APIView视图函数调用,这样更高效且避免请求构造的繁琐操作。
  • 外部请求可添加异常捕获(如网络错误、超时错误),返回更具体的错误信息。

内容的提问来源于stack exchange,提问作者user3521180

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 22:00:12