[Django]-Django rest framework : How to download image with this image send directly in the body

6👍

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.

👤Enix

0👍

I took the solution from https://www.py4u.net/discuss/185229 Answer number one and fixed it (it did not work for me, gave UnicodeDecodeError because file mus have been opened like open(img.path, 'rb'))

Full solution:

views.py

class PassthroughRenderer(renderers.BaseRenderer):
"""
    Return data as-is. View should supply a Response.
"""
media_type = ''
format = ''

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

class MeasuringPointImagesViewset(AbstractViewset):
    queryset = MeasuringPointImage.objects.all()
    serializer_class = MeasuringPointImageSerializer
    filter_class = MeasuringPointImageFilter

    @action(
        methods=[RequestMethods.GET.value.lower()],
        detail=True,
        url_path='download',
        url_name='download',
        renderer_classes=(PassthroughRenderer,)
    )
    def download(self, request, *args, **kwargs):
    
        instance: MyClassImage = self.get_object()
    
        img = instance.image
        response = FileResponse(open(img.path, 'rb'),     content_type='image/*')
        response['Content-Length'] = os.path.getsize(img.name)
        response['Content-Disposition'] = "attachment; filename=%s" % img.name
        return response

Leave a comment