returning zip for download from view in django - django

I try to download a zip file in my Django application.
How should I return it from the view?
I tried the code below, but I get some kind of alert in the browser with the content of the file inside my zip.
What am I doing wrong?
def download_logs(request):
date = datetime.datetime.now().__str__().replace(" ", "_").split(".")[0]
os.system("df -h . > /tmp/disk_space")
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'filename=logs_%s.zip' % date
files = []
files.append("/tmp/disk_space")
buffer = StringIO()
zip = zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED)
for name in files:
file = open(name, "r")
zip.writestr(name, file.read())
file.close()
zip.close()
buffer.flush()
ret_zip = buffer.getvalue()
buffer.close()
response.write(ret_zip)
return response

You should tell the browser to treat the response as a file attachment.
From the docs, you should do something like:
>> response = HttpResponse(my_data, mimetype='application/vnd.ms-excel')
>>> response['Content-Disposition'] = 'attachment; filename=foo.xls'

Here is a link to actual working code for building a ZipFile in memory and returning it to the user as a file to download: django-rosetta's view.py

Related

the filename of pdf file doesnt work correctly with wkhtmltopdf

I have a button download in my Django project, where I can export the report for a certain date in a pdf format. Everything works fine on my laptop with Linux, but when I set the project in the local server of our company, the name of the file is showing without a date.
Here is my code:
template_name = 'pdf.html'
template = get_template(template_name)
html = template.render({"data": data, "date":date, "index":index})
if 'DYNO' in os.environ:
print('loading wkhtmltopdf path on heroku')
WKHTMLTOPDF_CMD = subprocess.Popen(
['which', os.environ.get('WKHTMLTOPDF_BINARY', 'wkhtmltopdf-pack')],
stdout=subprocess.PIPE).communicate()[0].strip()
else:
print('loading wkhtmltopdf path on localhost')
WKHTMLTOPDF_CMD = ('/usr/local/bin/wkhtmltopdf/bin/wkhtmltopdf')
config = pdfkit.configuration(wkhtmltopdf=WKHTMLTOPDF_CMD)
options = {
'margin-bottom': '10mm',
'footer-center': '[page]'
}
pdf = pdfkit.from_string(html, False, configuration=config, options=options)
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="otchet-{}.pdf"'.format(date)
return response
when I download locally, the name of the file is - otchet-2021-06-30.pdf
but on server, it looks like - otchet%20.pdf
I have no idea, how to fix it...
Just a thought. Use an f string.
response['Content-Disposition'] = f'attachment; filename="otchet-{date}.pdf"'

Return Zip file with HttpResponse using StringIO, Django, Python

I'm trying to return a zip file with HttpResponse, using StringIO() because i'm not storing in DB or Harddrive.
My issue is that my response is returning 200 when i request the file, but the OS never ask me if i want to save the file, or the file is never saved. i think that the browser is reciving the file because i have seen on the Network Activity (inspect panel) and it says than a 6.4 MB file type zip is returned.
I'm taking a .step file (text file) from a DB's url, extracting the content, zipping and returning, that's all.
this my code:
def function(request, url_file = None):
#retrieving info
name_file = url_file.split('/')[-1]
file_content = urllib2.urlopen(url_file).read()
stream_content = StringIO(file_content)
upload_name = name_file.split('.')[0]
# Create a new stream and write to it
write_stream = StringIO()
zip_file = ZipFile(write_stream, "w")
try:
zip_file.writestr(name_file, stream_content.getvalue().encode('utf-8'))
except:
zip_file.writestr(name_file, stream_content.getvalue().encode('utf-8', 'ignore'))
zip_file.close()
response = HttpResponse(write_stream.getvalue(), mimetype="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename=%s.zip' % upload_name
response['Content-Language'] = 'en'
response['Content-Length'] = write_stream.tell()
return response

csv download doesn't occur without error in Django

I am implementing csv donwloand function referring to this page.
Even though I don't get any error message, cannot get csv file downloaded.
Does anyone know what is the problem for this implementation?
Below is the code to download csv file from database.
class timeCSVexport(View):
def get(self,request,pk,keyword):
key=keyword.replace("_"," ")
queryset=timeseries.objects.filter(html__pk=pk).filter(keyword=key)
bio = BytesIO()
data=json.loads(list(queryset)[0].df)
df=pd.DataFrame.from_dict(data,orient='index').T
df.index=pd.to_datetime(df.index)
df1=df.sort_index()
sheet=key[:31] if len(key)>31 else key
print (sheet)
writer=pd.ExcelWriter(bio,engine='xlsxwriter')
df1.to_excel(writer,sheet_name=sheet)
writer.save()
bio.seek(0)
workbook=bio.getvalue()
response = StreamingHttpResponse(workbook,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % pk
return response

Cannot download file in Django

I am trying to figure out how to download files in Django.I went through a couple of answers on stackoverflow and tried out this:
views.py
def download():
file = open("DemoCSV.csv", "r")
response = HttpResponse(file,content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="DemoCSV.csv"'
return response
The file DemoCSV.csv is in the same folder as my app.
When I hit the url from the browser,I cannot download the file.This error message is shown:
TypeError at /resources/download_files
download() takes 0 positional arguments but 1 was given
What am I missing?
It looks like download is a view, as such it's expected to take a single parameter, an HttpRequest object. so change as follows
def download(request):
file = open("DemoCSV.csv", "r")
response = HttpResponse(file,content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="DemoCSV.csv"'
return response

How to serve a django-webodt file to users?

I'm trying to allow users to export some of their database data. I am using django-webodt to create a .odt file from their data. I then am trying to allow them to download it. The file is created just fine, but when it downloads it seems to download a blank file. I think there is some difference between where the server is looking for the file and where it actually is. I was wondering how to get this to work properly? I'm relatively new to django so any help would be appreciated. The code I have is below:
def downloadBook(request, val):
template = webodt.ODFTemplate('conversion.odt')
context = dict(ideas=Book.objects.getIdeaSet(int(val)))
document = template.render(Context(context))
file_name = os.path.basename(document.name)
path_to_file = os.path.dirname(document.name)
response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
return response
I did the following and it works:
from django.template import Context
from webodt import ODFTemplate
template = ODFTemplate('template_file.odt')
context = { 'some_dict': '' }
document = template.render(Context(context))
response = HttpResponse(document.read(), mimetype='application/vnd.oasis.opendocument.text')
response['Content-Disposition'] = "attachment; filename=fancy-filename-as-you-like.odt"
document.close() # delete the document on /tmp
return response