Django define name of file to serve - python

I have wrote a code which let user to download a file. This is the code :
def download_file(request, ref):
filepath = "/home/jedema/code_"+ref+".txt"
filename = os.path.basename(filepath)
final_filename = "code.txt"
return serve(request, filename, os.path.dirname(filepath))
I want to define the file name that user will download. At the moment, the name of downloaded file is the URL after my domain name.
Do you know how to define the name of file downloaded by user ?

You need to set the Content-Dispositionheader in your response. First of all you shouldn't use the serve() view, to deliver the file, because it only works as long as DEBUG = True is set.
With a look at the Django Docs something like the following should do the trick
def download_file(request, ref):
filepath = "/home/jedema/code_"+ref+".txt"
filename = os.path.basename(filepath)
final_filename = "code.txt"
with open(filepath) as f:
response = HttpResponse(f.read(), content_type='text/plain')
response['Content-Disposition'] = 'attachment; filename="%s"' % final_filename
return response
I haven't tested it but it should be a hint into the right direction

Related

Download zip file with Django

I'm quite new on Django and i'm looking for a way to dwonload a zip file from my django site but i have some issue when i'm running this piece of code:
def download(self):
dirName = settings.DEBUG_FOLDER
name = 'test.zip'
with ZipFile(name, 'w') as zipObj:
# Iterate over all the files in directory
for folderName, subfolders, filenames in os.walk(dirName):
for filename in filenames:
# create complete filepath of file in directory
filePath = os.path.join(folderName, filename)
# Add file to zip
zipObj.write(filePath, basename(filePath))
path_to_file = 'http://' + sys.argv[-1] + '/' + name
resp= {}
# Grab ZIP file from in-memory, make response with correct MIME-type
resp = HttpResponse(content_type='application/zip')
# ..and correct content-disposition
resp['Content-Disposition'] = 'attachment; filename=%s' % smart_str(name)
resp['X-Sendfile'] = smart_str(path_to_file)
return resp
I get:
Exception Value:
<HttpResponse status_code=200, "application/zip"> is not JSON serializable
I tried to change the content_type to octet-stream but it doesn't work
And to use a wrapper as followw:
wrapper = FileWrapper(open('test.zip', 'rb'))
content_type = 'application/zip'
content_disposition = 'attachment; filename=name'
# Grab ZIP file from in-memory, make response with correct MIME-type
resp = HttpResponse(wrapper, content_type=content_type)
# ..and correct content-disposition
resp['Content-Disposition'] = content_disposition
I didn't find useful answer so far but maybe I didn't search well, so if it seems my problem had been already traited, feel free to notify me
Thank you very much for any help
You have to send the zip file as byte
response = HttpResponse(zipObj.read(), content_type="application/zip")
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(name)
return response
I would do like this:
(Caveat I use wsl so the python function will make use of cmd lines)
In view:
import os
def zipdownfun(request):
""" Please establish in settings.py where media file should be downloaded from.
In my case is media with a series of other folders inside. Media folder is at the same level of project root folder, where settings.py is"""
file_name = os.path.join(MEDIA_URL,'folder_where_your_file_is','file_name.zip')
"""let us put the case that you have zip folder in media folder"""
file_folder_path = os.path.join(MEDIA_URL,'saving_folder')
"""The command line takes as first variable the name of the
future zip file and as second variable the destination folder"""
cmd = f'zip {file_name} {file_folder_path}'
"""With os I open a process in the background so that some magic
happens"""
os.system(cmd)
"""I don't know what you want to do with this, but I placed the
URL of the file in a button for the download, so you will need
the string of the URL to place in href of an <a> element"""
return render(request,'your_html_file.html', {'url':file_name})
The db I have created, will be updated very often. I used a slightly different version of this function with -r clause since I had to zip, each time, a folder. Why I did this? The database I have created has to allow the download of this zipped folder. This folder will be updated daily. So this function basically overwrites the file each time that is downloaded. It will be so fresh of new data each time.
Please refer to this page to understand how to create a button for the download of the generated file.
Take as reference approach 2. The URL variable that you are passing to the Django template should be used at the place of the file (screenshot attached)
I hope it can help!

django error:can't specify the download filename

def download(request):
f = open("next_op.xls")
data = f.read()
f.close()
response = HttpResponse(data, content_type = './application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="nextop.xls"'
return response
When I use this code, I can download the file correctly, but the file name is invalid. I get the file name "download", and I found the response header doesn't include the Content-Disposition after I download the file.
you may need this:
fd = open(file, 'rb')
return FileResponse(fd, as_attachment=True, filename='xxx')

Serving Excel(xlsx) file to the user for download in Django(Python)

I'm trying create and serve excel files using Django. I have a jar file which gets parameters and produces an excel file according to parameters and it works with no problem. But when i'm trying to get the produced file and serve it to the user for download the file comes out broken. It has 0kb size. This is the code piece I'm using for excel generation and serving.
def generateExcel(request,id):
if os.path.exists('./%s_Report.xlsx' % id):
excel = open("%s_Report.xlsx" % id, "r")
output = StringIO.StringIO(excel.read())
out_content = output.getvalue()
output.close()
response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
args = ['ServerExcel.jar', id]
result = jarWrapper(*args) # this creates the excel file with no problem
if result:
excel = open("%s_Report.xlsx" % id, "r")
output = StringIO.StringIO(excel.read())
out_content = output.getvalue()
output.close()
response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
return HttpResponse(json.dumps({"no":"excel","no one": "cries"}))
I have searched for possible solutions and tried to use File Wrapper also but the result did not changed. I assume i have problem with reading the xlsx file into StringIO object. But dont have any idea about how to fix it
Why on earth are you passing your file's content to a StringIO just to assign StringIO.get_value() to a local variable ? What's wrong with assigning file.read() to your variable directly ?
def generateExcel(request,id):
path = './%s_Report.xlsx' % id # this should live elsewhere, definitely
if os.path.exists(path):
with open(path, "r") as excel:
data = excel.read()
response = HttpResponse(data,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
# quite some duplication to fix down there
Now you may want to check weither you actually had any content in your file - the fact that the file exists doesn't mean it has anything in it. Remember that you're in a concurrent context, you can have one thread or process trying to read the file while another (=>another request) is trying to write it.
In addition to what Bruno says, you probably need to open the file in binary mode:
excel = open("%s_Report.xlsx" % id, "rb")
You can use this library to create excel sheets on the fly.
http://xlsxwriter.readthedocs.io/
For more information see this page. Thanks to #alexcxe
XlsxWriter object save as http response to create download in Django
my answer is:
def generateExcel(request,id):
if os.path.exists('./%s_Report.xlsx' % id):
with open('./%s_Report.xlsx' % id, "rb") as file:
response = HttpResponse(file.read(),content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
# quite some duplication to fix down there
why using "rb"? because HttpResponse class init parameters is (self, content=b'', *args, **kwargs), so we should using "rb" and using .read() to get the bytes.

How to open a .txt file in Django?

I have a Django app in which when I click on the link then I can download a .txt file. Now instead of downloading that file I need to open that file (in 'r' mode). I'm trying to do something similar to that of mail attachments that is when we click on the attachment then it opens up instead of downloading. How can I do it ? The following code is to download the .txt file :
def fetch_logfile(request,logfile):
try:
folder,log,_ = logfile.split("/")
pathRelative = r"/LogFile/"+log
folder,log,_ = logfile.split("/")
pathRelative = r"/LogFile/"+log
path = pathRelative[1::]
os.startfile(pathRelative,open)
file_path =os.getcwd()+ '/' +pathRelative
file_wrapper = FileWrapper(file(file_path,'rb'))
file_mimetype = mimetypes.guess_type(file_path)
response = HttpResponse(file_wrapper, content_type=file_mimetype )
response['X-Sendfile'] = file_path
response['Content-Length'] = os.stat(file_path).st_size
nameOnly = log.split('/')
response['Content-Disposition'] = 'attachment; filename=%s' % nameOnly[len(nameOnly)-1]
return response
except:
## do something else
The following code works which I have tried in Python IDLE but when I try the same in Django then it doesn't work. I'm not sure if this is the right way either.Please advice me on this.
def fetch_Logfile(request,logfile):
import os,sys
path = "C:\\Users\\welcome\\Desktop\\mysite\\LogFile\\"+"756849.txt"
os.startfile(path,open)
## do something with logfile and request
def fetch_Logfile(request,logfile):
path = "C:\\Users\\welcome\\Desktop\\mysite\\LogFile\\"+"756849.txt"
import webbrowser
webbrowser.open(path)
## do something with logfile and request
def fetch_Logfile(request,logfile):
import win32api,os,subprocess
path = "C:\\Users\\welcome\\Desktop\\mysite\\LogFile\\"+"756849.txt"
filename_short = win32api.GetShortPathName(path)
subprocess.Popen('start ' + filename_short, shell=True )
subprocess.Popen('start ' + path, shell=True )
## do something with logfile and request
my_file = open(file_path, 'r')
response = HttpResponse(my_file.read(), mimetype='text/plain')
response['Content-Disposition'] = 'inline;filename=some_file.txt'
return response
Here is the MIME Types – Complete List
You can provide mimetype = ' / ' based on the file extension by referencing the mime type list.

Unknown and Damaged Archive in django

This is code to download files but when file downloads and i open them :the archive is unknown and damaged. Can you please help me to solve this problem here code is:
def download(request):
file_name =request.GET.get('file_name', '')
the_file = "C:\\Users\\CV_Uploads\\uploadfiles\\uploadfiles\\uploaded_files\\1395901478_89_uploadfiles.rar"
filename = os.path.basename(the_file)
response = HttpResponse(FileWrapper(open(the_file)),
content_type=mimetypes.guess_type(the_file)[0])
response['Content-Length'] = os.path.getsize(the_file)
response['Content-Disposition'] = "attachment; filename=%s" % filename
return response
When you are dealing with paths you should use raw string .
use
the_file = r"C:\Users\CV_Uploads\uploadfiles\uploadfiles\uploaded_files\1395901478_89_uploadfiles.rar"

Categories

Resources