1

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

I'm using python 3, Django==1.10.5 and djangorestframework==3.5.3, drf-extensions==0.3.1 (for the nested routes) and django-extra-fields==0.9 for the ImageField.

(I have tried without django-extra-fields, it's the same)

I have already found one solution (thx a lot Enix ;p) with the base64 here :Django rest framework : How to download image with this image send directly in the body

But my boss doesn't want base64 and just want the binary inside the body response.

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()  # This is just for the exemple.
        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 

I have made some test with :

django.core.files.File, filewrapper, deactivate the serializer

but have not yield desired results...

If someone find out what I'm doing wrong or maybe forgot something in the settings ? Any help regarding the same would be much appreciated!

Community
  • 1
  • 1
Bat
  • 143
  • 1
  • 3
  • 11

1 Answers1

4

Ok, I found my mistake...

I was trying to override get_queryset... and not the get method which doesn't work too because I need to override the list method!

I need to sleep a little bit more ;p

Here is a solution that work's great for me with Streaming for download large file if needed :

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 list(self, request, *args, **kwargs):

            image = Image.objects.get(pk=get_your_good_record)
            filename = image.image_file
            size = filename.size

            content_type_file = mimetypes.guess_type(filename.path)[0]

            response = StreamingHttpResponse(open(image.image_file.path, 'rb'), content_type=content_type_file)
            response['Content-Disposition'] = "attachment; filename=%s" % str(filename)
            response['Content-Length'] = size

            return response

So easy ;p

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Bat
  • 143
  • 1
  • 3
  • 11