Reputation: 29
I am trying to use FileResponse.set_header()
to set Content-Disposition to attachment, so that Audio file can be downloaded rather than playing on the browser, in my python/django powered website.
is there any way i can implement this code bellow to make it work?
song = models.song.objects.filter(id__exact=song_id).first()
file_name = ntpath.basename(song.songfile.url)
content_type = 'audio/mpeg'
with open(identify_song.songfile.path, 'rb') as my_f:
file_like = my_f
response = FileResponse(my_f, content_type=content_type, as_attachment=True, filename="{}".format(file_name))
response['Content-Disposition'] = 'attachment; filename="{}"'.format(file_name)
size = response['Content-Length'] = os.path.getsize(identify_song.songfile.path)
#print(file_name)
return(response)
this code does not give me any error but it's not working.
So i discovered about FileResponse.set_header()
in the django doc, so i tried using it like so.
`song = models.song.objects.filter(id__exact=song_id).first()
file_name = ntpath.basename(song.songfile.url)
FileResponse.set_headers(file_name, filelike='audio/mpeg', as_attachment=True)`
Then i got an error AttributeError: 'str' object has no attribute 'filename'. please can anyone help me out, or if there is another way to do that in django i will so much appreciate someone's help. Or any other possible way i can set my Content-Disposition, in django, Nginx or in Javascript.
Upvotes: 2
Views: 7060
Reputation: 156
There is no need to explicitly set the headers, so long as you pass in a file stream like so:
song = models.song.objects.filter(id__exact=song_id).first()
file_name = ntpath.basename(song.songfile.url)
content_type = 'audio/mpeg'
return FileResponse(
open(identify_song.songfile.path, 'rb'),
content_type=content_type,
as_attachment=True,
filename=file_name
)
Here is the documentation from Django.
Upvotes: 0
Reputation: 699
There is no answer to this question as the method 'FileResponse.set_header()' can be called with a file like object only and it makes some guesses about the header which are not reliable if you use file types that are rather exotic. At least you can overwrite this function that returns nothing but only sets the header information or you can do this little task in your code yourself. Here is my example using an in-memory string buffer.
filename = "sample.creole"
str_stream = StringIO()
str_stream.write("= Some Creole-formated text\nThis is creole content.")
str_stream.seek(0)
response = FileResponse(str_stream.read())
response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename)
response.headers['Content-Type'] = 'application/creole'
return response
With that approach yo can still use the default 'FileResponse.set_header()' functionality to set the 'Content-Length' which works properly. As the other 'FileResponse' parameters such as 'as_attachment' and 'filename' don't work as reliable. Probably nobody noticed yet as 'FileResponse' is rarely used, and as a matter of fact the same functionality can be implemented using 'HttpResponse'.
response = HttpResponse(content_type='application/creole')
response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename)
response.write(str_stream.read())
return response
Upvotes: 2
Reputation: 862
The utldol it is a python file that contains a function, that generates a xls file. The function returns smth like these :
outcome, error = None, None
try:
........
........
file = open(output.get("filedir"), 'rb')
outcome = {
"file": file, "filename": output.get("filename"),
}
except Exception as ex:
error = str(ex)
return [outcome, error]
Upvotes: 0
Reputation: 862
I have been working all day with this functionality in order to download a generated file, lemme share you how I did it, it worked like a charm.
documentation : https://docs.djangoproject.com/en/3.0/ref/request-response/
http header 'Content-Disposition': https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
try:
wdata = request.GET
download = wdata.get("download") or ''
allowed_params = [
'template', 'bases',
]
if download in allowed_params:
out, err = utldol.download_file(download, request)
if err:
raise ValueError(str(err))
else:
raise ValueError(str('Parameter not recognized'))
file = FileResponse(
out.get("file"), filename=out.get("filename"),
)
file['Content-Disposition'] = 'attachment; filename="{}"'.format(
out.get("filename")
)
return file
except Exception as ex:
return HttpResponseBadRequest(str(ex))
out.get("file")
out.get("filename")
Hope my experience would be helpful, any views, please just lemme know.
greetings,
Upvotes: 3