How to return generated file download with Django REST Framework?

This may work for you:

file_path = file_url
FilePointer = open(file_path,"r")
response = HttpResponse(FilePointer,content_type='application/msword')
response['Content-Disposition'] = 'attachment; filename=NameOfFile'

return response.

For FrontEnd code refer this


I am using DRF and i found a view code to download file, which would be like

from rest_framework import generics
from django.http import HttpResponse
from wsgiref.util import FileWrapper

class FileDownloadListAPIView(generics.ListAPIView):

    def get(self, request, id, format=None):
        queryset = Example.objects.get(id=id)
        file_handle = queryset.file.path
        document = open(file_handle, 'rb')
        response = HttpResponse(FileWrapper(document), content_type='application/msword')
        response['Content-Disposition'] = 'attachment; filename="%s"' % queryset.file.name
        return response

and url.py will be

path('download/<int:id>/',FileDownloadListAPIView.as_view())

I am using React.js in frontend and i get a response like

handleDownload(id, filename) {
  fetch(`http://127.0.0.1:8000/example/download/${id}/`).then(
    response => {
      response.blob().then(blob => {
      let url = window.URL.createObjectURL(blob);
      let a = document.createElement("a");
      console.log(url);
      a.href = url;
      a.download = filename;
      a.click();
    });
  });
}

and after i got successful in downloading a file which also opens correctly and i hope this gonna work. Thanks


Here's an example of returning a file download directly from DRF. The trick is to use a custom renderer so you can return a Response directly from the view:

from django.http import FileResponse
from rest_framework import viewsets, renderers
from rest_framework.decorators import action

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 ExampleViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Example.objects.all()

    @action(methods=['get'], detail=True, renderer_classes=(PassthroughRenderer,))
    def download(self, *args, **kwargs):
        instance = self.get_object()

        # get an open file handle (I'm just using a file attached to the model for this example):
        file_handle = instance.file.open()

        # send file
        response = FileResponse(file_handle, content_type='whatever')
        response['Content-Length'] = instance.file.size
        response['Content-Disposition'] = 'attachment; filename="%s"' % instance.file.name

        return response

Note I'm using a custom endpoint download instead of the default endpoint retrieve, because that makes it easy to override the renderer just for this endpoint instead of for the whole viewset -- and it tends to make sense for list and detail to return regular JSON anyway. If you wanted to selectively return a file download you could add more logic to the custom renderer.