4π
I solved my problem by saving file in media folder and sending of the link of it to front-end.
@permission_classes((permissions.IsAdminUser,))
class StudentDocxViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
def retrieve(self, request, *args, **kwargs):
template = webodt.ODFTemplate('test.odt')
queryset = Pupils.objects.get(id=kwargs['pk'])
serializer = StudentSerializer(queryset)
context = dict(serializer.data)
document = template.render(Context(context))
doc = converter().convert(document, format='doc')
p = u'docs/cards/%s/%s_%s.doc' % (datetime.now().date(), context[u'surname'], context[u'name'])
path = default_storage.save(p, doc)
return response.Response(u'/media/' + path)
And handled this like in my front-end (AngularJS SPA)
$http(req).success(function (url) {
console.log(url);
window.location = url;
})
25π
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.
- [Django]-How to paginate Django with other get variables?
- [Django]-TypeError: data.forEach is not a function
- [Django]-Django "Remember Me" with built-in login view and authentication form
13π
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
- [Django]-Django models without database
- [Django]-How can I add a button into django admin change list view page
- [Django]-How do I use the built in password reset/change views with my own templates
10π
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
- [Django]-How to backup a django db
- [Django]-How to create a fixture file
- [Django]-Where does django install in ubuntu
6π
For me, using Python 3.6, Django 3.0, and DRF 3.10, The problem came from using the wrong type of response. I needed to use a django.http.HttpResponse
, as seen below:
from django.http import HttpResponse
...
with open('file.csv', 'r') as file:
response = HttpResponse(file, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=file.csv'
return response
- [Django]-How to break "for loop" after 1 iteration in Django template
- [Django]-What is the canonical way to find out if a Django model is saved to db?
- [Django]-Whats the simplest and safest method to generate a API KEY and SECRET in Python
2π
In models.py
class Attachment(models.Model):
file = models.FileField(upload_to=attachment_directory_path, blank=True, null=True)
...
@property
def filename(self):
return self.file.name.split('/')[-1:][0]
in views.py
import mimetypes
from django.http import FileResponse
class AttachmentViewSet(ModelViewSet):
...
@action(methods=['GET'], detail=True)
def download(self, request, **kwargs):
att = self.get_object()
file_handle = att.file.open()
mimetype, _ = mimetypes.guess_type(att.file.path)
response = FileResponse(file_handle, content_type=mimetype)
response['Content-Length'] = att.file.size
response['Content-Disposition'] = "attachment; filename={}".format(att.filename)
return response
and in frontend, I used axios for download files. api
is axios client.
export function fileDownload(url, filename){
return api.get(url, { responseType: 'blob' })
.then((response)=>{
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
})
}
hope that it helps
- [Django]-How to ignore directories when running Django collectstatic?
- [Django]-Django gives Bad Request (400) when DEBUG = False
- [Django]-Get class name of django model
0π
Using django-downloadview this can be done like so:
from rest_framework.decorators import action
from django_downloadview import ObjectDownloadView
class DocumentViewSet(viewsets.ReadOnlyModelViewSet):
@action(detail=True)
def download(self, request, pk):
return ObjectDownloadView.as_view(
model=, # your model here
)(request, pk=pk)
The viewset can then be registered via DRF routers.
- [Django]-How to use "AND" in a Django filter?
- [Django]-Serving large files ( with high loads ) in Django
- [Django]-Django models ForeignKey on_delete attribute: full meaning?
0π
class FileDownloadListView(generics.ListAPIView):
def get(self, request, id):
media = Media.objects.get(id=id)
filepath = media.video.path
mimetype, _ = mimetypes.guess_type(filepath)
filename = os.path.basename(media.video.name)
with open(filepath, 'rb') as file:
response = HttpResponse(FileWrapper(file), content_type=mimetype)
response['Content-Disposition'] = f'attachment; filename={filename}'
return response
path('media/download/<int:id>/', FileDownloadListView.as_view()),
- [Django]-Django :How to integrate Django Rest framework in an existing application?
- [Django]-Which database engine to choose for Django app?
- [Django]-Is not JSON serializable