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

如何在Django Rest Framework响应中展示带密钥验证的外部API图片

问题分析与解决方案

一、核心错误定位

你当前代码的问题是直接把requests.get返回的Response实例传给了Django的HttpResponse,但Django响应需要的是字节内容而非requests的响应对象,这就是Chrome报500错误的根本原因(Postman对参数兼容性更强,但代码逻辑本身不规范)。

二、修正后的图片转发视图

修改视图函数,提取外部API返回的字节内容再包装成合法响应:

from rest_framework.decorators import api_view
from rest_framework.response import Response
import requests

@api_view(['GET'])
def random_image(request):
    # 调用带私钥的外部图片API
    external_res = requests.get('你的外部API地址(含私钥)', timeout=10)
    # 校验外部请求是否成功
    if external_res.status_code != 200:
        return Response({"error": "获取外部图片失败"}, status=external_res.status_code)
    
    # 返回图片字节内容
    return Response(
        external_res.content,
        content_type="image/jpeg"
    )

也可以用Django原生HttpResponse实现:

from django.http import HttpResponse

# 替换上述返回语句
return HttpResponse(
    external_res.content,
    content_type="image/jpeg"
)

三、同时返回模型数据与图片的两种可行方案

方案1:返回模型数据+图片接口URL(推荐)

遵循RESTful规范,不直接返回二进制图片,而是返回模型数据和你的DRF图片接口地址,前端后续单独请求图片:

from .models import YourModel
from rest_framework import serializers

class YourModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = YourModel
        fields = ['id', '你的字符字段名']

@api_view(['GET'])
def model_with_image(request):
    # 按业务逻辑获取模型实例
    model_instance = YourModel.objects.first()
    serializer = YourModelSerializer(model_instance)
    
    # 组装响应数据:模型数据 + 图片接口的绝对URL
    response_data = serializer.data
    response_data['image_url'] = request.build_absolute_uri('/api/random-image/')  # 替换为你的图片接口路径
    
    return Response(response_data)

前端拿到数据后,直接将image_url赋值给<img>的src属性即可加载图片。

方案2:返回模型数据+Base64编码图片

若需一次性返回所有内容,可将图片转为Base64字符串与模型数据一起返回:

import base64

@api_view(['GET'])
def model_with_image_base64(request):
    model_instance = YourModel.objects.first()
    serializer = YourModelSerializer(model_instance)
    
    external_res = requests.get('你的外部API地址(含私钥)', timeout=10)
    if external_res.status_code != 200:
        return Response({"error": "获取外部图片失败"}, status=external_res.status_code)
    
    # 将图片转为Base64格式
    image_base64 = base64.b64encode(external_res.content).decode('utf-8')
    response_data = serializer.data
    response_data['image_base64'] = f"data:image/jpeg;base64,{image_base64}"
    
    return Response(response_data)

前端拿到后直接将image_base64赋值给<img>的src即可,但注意Base64会让数据体积增大约30%,大图片不建议使用此方案。

四、额外优化建议

  • 给外部请求添加超时时间,避免后端因外部服务异常挂起
  • 对外部图片做缓存(用Django缓存框架或存储到对象存储),减少重复请求
  • 不要硬编码私钥,用环境变量(如os.getenv('EXTERNAL_API_KEY'))管理,提升安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:45:40