Django REST API 公开图像

Posted

技术标签:

【中文标题】Django REST API 公开图像【英文标题】:Django REST API to expose images 【发布时间】:2014-12-24 14:41:29 【问题描述】:

我有一个 django 应用程序,我想公开模型图像,这样当我请求 /image/school_id/400 时,它会返回 ID 为 school_id 的学校图像,并将其裁剪并调整为 400x400 像素的框。这是我尝试过的

@api_view(['GET', 'POST'])
def image_view(request,  school_id, size):

    image = School.objects.get(school__pk=school_id).image
    resized_img = image #Handle resizing here

    return Response(resized_img, content_type='*/*')

我得到的只是一个错误'utf8' codec can't decode byte 0xff in position 0: invalid start byte

我如何返回图像? 我正在使用 Django-rest-framework http://www.django-rest-framework.org/api-guide/renderers#advanced-renderer-usage

【问题讨论】:

【参考方案1】:

您正在尝试返回原始图像数据并让 Django REST Framework 呈现响应。由于响应不应因所选格式而有所不同,因此您应该使用原始 HttpResponse 对象。

return HttpResponse(resized_img, content_type="image/png")

请注意,content_type 应反映返回响应的内容类型,该内容类型应与正在调整大小的图像的内容类型相匹配。


您收到的错误是因为 Renderer 类需要基于文本的响应,而不是图像数据。 Django REST Framework 不会将自定义渲染器应用到 HttpResponse 类,只会应用到 Django REST Framework Response 类。

【讨论】:

从 Django 1.8 开始还有 django.http.FileResponse【参考方案2】:

我知道这是一个很老的问题,但我找到了解决这个问题的方法。 您可以使用 Django Rest Framework 中的 custom renderer 通过 Response 返回图像。 例如:

class CustomRenderer(renderers.BaseRenderer):
    media_type = 'image/png'
    format = 'png'
    charset = None
    render_style = 'binary'

    def render(self, data, media_type=None, renderer_context=None):
        return data

在视图中,您必须通过以下方式调用此渲染器:

装饰器:@renderer_classes((CustomRenderer,))

渲染器类:renderer_classes = (CustomRenderer, )

注意。记住分号

如果你使用像 @action 这样的装饰器,你可能无法通过装饰器调用你的渲染器。在这种情况下,您必须在 @action 装饰器中使用 renderer_classes

@action(methods=['get'], detail=True, renderer_classes=(CustomRenderer,))

【讨论】:

以上是关于Django REST API 公开图像的主要内容,如果未能解决你的问题,请参考以下文章

通过 REST API 公开 Redshift 表

将 GraphQL Schema 公开为 REST api 的方法都有哪些?

向 Web 公开 Cassandra REST API 的最佳方式是啥?

读取 kafka 主题并通过 Rest API 公开数据以供 prometheus 抓取(Nodejs)

编写一个包装器将现有的 REST API 公开为 SOAP Web 服务?

尝试使用 REST API 公开对象时出现“拒绝访问。提供的范围未经授权”错误