Django rest framework : How to download image with

2019-07-18 04:14发布

I need to return an Image directly in the body request, but i get in response a generated file with no extension and an empty array/json inside...

I'm using python 3, Django==1.10.5 and djangorestframework==3.5.3

My 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)

My serializers.py

class ImageSerializer(serializers.ModelSerializer):

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

My 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 

If someone find what I'm doing wrong, I will really appreciate. Thx a lot ;p

Edit : i have tryed with django.core.files.File, filewrapper and tryed to desactivate the serializer without effect.

1条回答
看我几分像从前
2楼-- · 2019-07-18 04:47

You can use base64 module to encode the image file to base64 format (a raw string), and then assigned it to a field to transfer your image.

I have updated your ImageSerializer to include a new filed named base64_image which is encoded from the model's image file with base64 format.

The following example is for your reference:

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

Finally, you can open a browser with url: http://localhost:8000/image/, and you will get the response like that:

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

How to show your image in front-end or app?

When your front-end get the json above, you need to convert the base64 format back to image raw data.

For Javascript:

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

How can I set Image source with base64

For iOS:

how to decode BASE64 encoded PNG using Objective C

For Android:

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

I have upload an example to GitHub. Hope it would help.

查看更多
登录 后发表回答