使用Django REST框架返回图像渲染

时间:2017-02-11 14:23:14

标签: python django django-rest-framework

我使用 Django REST Framework 上传了图片。现在我正在尝试返回与响应相同的图像。

views.py

class ImageUploadView(viewsets.ModelViewSet):
    queryset = ImageModel.objects.all()
    serializer_class = ImageSerializer

    def create(self, request, *args, **kwargs):
        userID = (request.data.get('userID'))
        serializer = self.get_serializer(data=request.data)
        if not UserModel.objects.filter(id=userID).exists():
            return Response(data={"detail": "Invalid UserID"})
        else:
            if serializer.is_valid():
                serializer.save()                
                return Response(ImageModel.objects.get(id=serializer.data['id']).image, content_type="image/png")
        return Response(data={"detail": "Serializer Error"})

通过使用上面的代码,我既没有得到有效的图像(它返回一个像图像一样的小方框)也没有错误
希望有人可以提供帮助,谢谢

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,并花了几个小时解决这个问题。操作方法如下:

1。创建自定义渲染器

首先,您需要创建一个称为自定义渲染器的东西。如果您想进一步了解什么是渲染器以及如何制作自定义渲染器,请使用link to the REST Framework's Renderers Documentation。在这种情况下,我们必须为 .jpg .png 文件制作自定义渲染器。为此,我建议您创建一个名为 custom_renderers.py 的文件,并将以下代码复制到其中:

custom_renderers.py

from rest_framework import renderers

class JPEGRenderer(renderers.BaseRenderer):
    media_type = 'image/jpeg'
    format = 'jpg'
    charset = None
    render_style = 'binary'

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

class PNGRenderer(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

2。导入渲染器,并通过

将它们包括在您的视图中

此后,如果您使用的是基于类的视图(或者如果使用的是方法,则必须导入刚创建的渲染,并将其包含在视图中的属性renderer_classes = [JPEGRenderer, PNGRenderer]中)基于视图的视图,您必须将其包含在装饰器@renderer_classes()下)

3。您的其余观点和return语句

如果您要投放图片或视图中的任何图片,则必须先使用收到的图片对象旁边的.open()打开图片或文件字段,然后在发送之前使用FileWrapper()包装图像(我在响应中得到一个小黑框的原因就像您在发送图像之前没有打开图像,也没有使用 FileWrapper())。因此,您的回应如下: return Response(FileWrapper(ImageModel.objects.get(id=serializer.data['id'])['image'].open())

我没有指定返回类型,因为在我的情况下返回类型是自动确定的。因此,您的 views.py 最终将类似于:

## All the other necessary imports

from path.to.custom_renderers import JPEGRenderer, PNGRenderer
from wsgiref.util import FileWrapper

#Also, I think this should rather be ImageDownloadView as the client would be downloading the image
class ImageUploadView(viewsets.ModelViewSet):
    renderer_classes = [JPEGRenderer, PNGRenderer]

    queryset = ImageModel.objects.all()
    serializer_class = ImageSerializer

    def create(self, request, *args, **kwargs):
        userID = (request.data.get('userID'))
        serializer = self.get_serializer(data=request.data)
        if not UserModel.objects.filter(id=userID).exists():
            return Response(data={"detail": "Invalid UserID"})
        else:
            if serializer.is_valid():
                serializer.save()                
                return Response(FileWrapper(ImageModel.objects.get(id=serializer.data['id'])['image'].open())
                # You can also specify the content_type in your response
        return Response(data={"detail": "Serializer Error"})

干杯!