Django休息框架:如何使用此图像下载图像直接发送到正文

时间:2017-03-18 12:52:09

标签: django image download django-rest-framework

我需要直接在body请求中返回一个Image,但是我得到了一个没有扩展名的生成文件和一个空数组/ json ...

我使用的是python 3,Django == 1.10.5和djangorestframework == 3.5.3

我的models.py

class Image(models.Model):
    class Meta:
        verbose_name = _('Image')
        verbose_name_plural = _('Images')

    creation_date = models.DateTimeField(
        help_text=_('Creation date'),
        auto_now_add=True,
        editable=False
    )

    modified_date = models.DateTimeField(
        help_text=_('Last modification date'),
        auto_now=True
    )

    image_file = models.ImageField(upload_to='', null=True)

我的serializers.py

class ImageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Image
        fields = ('image_file',)

我的views.py

class ImageViewSet(NestedViewSetMixin, viewsets.ModelViewSet):

    http_method_names = ['get', 'put']
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    pagination_class = None

    def get_queryset(self, *args, **kwargs):

        image = Image.objects.last()
        filename = image.image_file
        size = filename.size
        response = FileResponse(open(filename.path, 'rb'), content_type="image/png")
        response['Content-Length'] = size
        response['Content-Disposition'] = "attachment; filename=%s" % 'notification-icon.png'
        return response 

如果有人发现我做错了什么,我真的很感激。 很多; p

编辑:我尝试过使用django.core.files.File,filewrapper并尝试停用序列化程序而没有效果。

1 个答案:

答案 0 :(得分:2)

您可以使用base64模块将图像文件编码为base64格式(原始字符串),然后将其分配给字段以传输图像。

我已更新您的ImageSerializer以包含一个名为base64_image的新字段,该字段是使用base64格式从模型的图像文件中编码的。

以下示例供您参考:

serialisers.py

from django.core.files import File
import base64

class ImageSerializer(serializers.ModelSerializer):

    base64_image = serializers.SerializerMethodField()

    class Meta:
        model = Image
        fields = ('base64_image', 'id')

    def get_base64_image(self, obj):
        f = open(obj.image_file.path, 'rb')
        image = File(f)
        data = base64.b64encode(image.read())
        f.close()
        return data

views.py

class ImageViewSet(viewsets.ModelViewSet):
    http_method_names = ['get', 'put']
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    pagination_class = None

urls.py

from rest_framework.routers import DefaultRouter

# Register viewset
router = DefaultRouter()
router.register(r'image', ImageViewSet)
urlpatterns += router.urls

最后,您可以使用网址http://localhost:8000/image/打开浏览器,然后您会得到类似的响应:

[
    {
        "base64_image": "iVBORw0KGg.....",
        "id": 1
    }
]

如何在前端或应用中显示图像?

当您的前端获取上面的json时,您需要将base64格式转换回图像原始数据。

对于Javascript:

document.getElementById('img').setAttribute( 'src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEU.......');

How can I set Image source with base64

对于iOS:

how to decode BASE64 encoded PNG using Objective C

对于Android:

How to convert a Base64 string into a BitMap image to show it in a ImageView?

我已将示例上传到GitHub。希望它会有所帮助。