【问题标题】:Browsable Django REST API wrapper for external API calls用于外部 API 调用的可浏览 Django REST API 包装器
【发布时间】:2021-02-28 06:44:51
【问题描述】:

我正在为 Django 项目构建一个 RESTful 接口,我需要利用外部 API 来允许客户端和前端仅引用一个 Django API,而无需外部 API 的详细信息。

因此,我希望将外部 API 数据返回到可浏览的 API 页面,就像我自己的基于视图的 API 一样。

如何将来自外部 API 的 JSON 响应序列化到可浏览的 API 网页渲染器?

例如,我希望 mysite.fake/thing/details 返回与 externalapi.fake/thing/details 返回相同的 JSON,如下所示:

{"thing_id": "900404", "description": "Thing description", "value": "100.00", "location": "Bin 401"}

并将其显示在 DRF 的可浏览 API 中。

目前,我正在使用:

@api_view(('GET',))
@renderer_classes((JSONRenderer,))
def thing_finder(request, thing_id):
    """
    Get the current location for a thing
    http://localhost:8000/thing/find/9900404
    :param request: HTTP Request object
    :param thing_id: String - the thing ID
    :return: JSON - The Thing location JSON
    """
    a, b = THING_API_AUTH
    if request.method == 'GET':
        payload = {'thing_id': thing_id}
        r = requests.get(THING_API_AUTH, auth=HTTPBasicAuth(a, b), params=payload)
        if r.status_code == 200:
            data = json.loads(r.text)
            serializer = ThingFinderSerializer(data)
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response({"error": "Request failed"}, status=r.status_code)

settings.py我包括:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}

这可行(我认为),但它不会将结果格式化为 Browsable API。相反,我得到一个未格式化的页面,其中包含 JSON 转储到其中。我是否缺少模板要求?浏览器中的 URL 错误? settings.py 中的 BrowsableAPIRenderer 是否不足以默认呈现到 Browsable API? TIA。

【问题讨论】:

    标签: python json django django-rest-framework python-requests


    【解决方案1】:

    我解决了:

    from rest_framework.renderers import JSONRenderer, BrowsableAPIRendererenter
    @api_view(('GET',))
    @renderer_classes((JSONRenderer, BrowsableAPIRenderer))
    def thing_finder(request, thing_id):
        """
        Get the current location for a thing
        http://localhost:8000/thing/find/9900404
        :param request: HTTP Request object
        :param thing_id: String - the thing ID
        :return: JSON - The Thing location JSON
        """
        a, b = THING_API_AUTH
        if request.method == 'GET':
            payload = {'thing_id': thing_id}
            r = requests.get(THING_API_AUTH, auth=HTTPBasicAuth(a, b), params=payload)
            if r.status_code == 200:
                data = json.loads(r.text)
                serializer = ThingFinderSerializer(data)
                return Response(serializer.data, status=status.HTTP_200_OK)
            else:
                return Response({"error": "Request failed"}, status=r.status_code)
    

    这会在一个干净、格式化的页面中返回 Browsable API 呈现。

    【讨论】:

      【解决方案2】:

      这里不需要使用序列化器,作为返回 JSON 数据的外部源。您可以将 response.json() 方法用作

      @api_view(('GET',))
      @renderer_classes((JSONRenderer,))
      def thing_finder(request, thing_id):
          a, b = THING_API_AUTH
          if request.method == 'GET':
              payload = {
                  'thing_id': thing_id
              }
              response = requests.get(
                  THING_API_AUTH,
                  auth=HTTPBasicAuth(a, b),
                  params=payload
              )
              if response.status_code == 200:
                  return Response(response.json(), status=status.HTTP_200_OK)
              return Response({"error": "Request failed"}, status=response.status_code)

      【讨论】:

      • 我正在尝试获取响应以在 DRF 可浏览 API 中呈现 - 如果我使用您的方法,我会得到相同的未设置样式的页面,只返回原始 JSON。但是,对于原始 JSON,这是一个很好的提示。
      • 那么您期望的格式是什么?举个例子
      • 我不明白有什么区别。可能添加屏幕截图或图像可能有助于(我)了解情况
      • 我解决了 - 我需要将 BrowsableAPIRenderer 装饰器与 JSONRenderer 一起包含在内。谢谢
      猜你喜欢
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 2017-08-07
      • 2017-01-27
      • 2018-12-25
      • 2013-09-20
      • 2016-06-06
      • 1970-01-01
      相关资源
      最近更新 更多